From 58f591e5f69b51668fecf815eb5e0cb41122b1ba Mon Sep 17 00:00:00 2001 From: Xinwei Xiong <3293172751NSS@gmail.com> Date: Wed, 23 Aug 2023 09:09:51 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8Large=20refactoring=20projects:=20Open?= =?UTF-8?q?IM=20automation,=20scripting,=20and=20openimctl=20refactoring?= =?UTF-8?q?=20(#825)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: fix bin tools path Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: fix golang release file path Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: fix golang release file path Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: fix scripts and optimize Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: fix scripts path module Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: sync script code Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add lib and start scripts Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * ci: add copyright scripts Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * ci: add go-docs file and copyright scripts Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add scripts cross ower Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * style: Formatting code make lint path Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * style: Formatting code make lint path Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * style: Formatting code make lint path Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * style: Formatting code make lint path Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: chat scripts path bug Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: channge smail images Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add makefile feature Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add config and images log Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * style: Migrate directory to remove docker to images Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * style: formatting style Code Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: set opneim's bash logs Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: option scripts and docs Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add git cherry Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add git cherry Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: save all bash and docs labels Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: scripts feature extend Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add config path config Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add config path config Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add feat scripts Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add save scripts Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add save scripts Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add sctips help Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add start sctips help Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: save scripts file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: save all file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add openim server template file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add alot of system design Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: save all file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: save all file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add env config options Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add more robot details Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add more module explain Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add scripts environment details design Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add openim msgtransfer scripts Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add openim msgtransfer scripts Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add more design scripts Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add file save Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add file save Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add rpc build and start Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add rpc build and start Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add rpc build and start Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: save all images file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add scripts set Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add test options Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: fix config path file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: update config file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: update config file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: update config file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: update config file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add readme docs Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: save build scripts Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add all actions file Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add chat scripts name Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add all compose Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: commit tag Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: save server code Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add docker compose fix Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add docker compose fix Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add docker compose fix Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: save server code Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: optimize dockerfile option Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: optimize dockerfile option Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: optimize dockerfile option Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add all options Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add all options Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add more scrips Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add more options Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add more options Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add config path Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: Add some optimizations Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * fix: Add some optimizations Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: delele go work sum Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: delele go work sum Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * Delete go.work.sum * feat: delele go work sum Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * Update .env * feat: delele go work sum Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: delele go work sum Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: delele go work sum Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: delele go work sum Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add docker compose fix Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: add docker compose fix Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> * feat: delele go work sum Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> --------- Signed-off-by: Xinwei Xiong(cubxxw-openim) <3293172751nss@gmail.com> --- .dockerignore | 6 +- .env | 4 +- .github/release-drafter.yml | 51 ++ .github/sync.yml | 2 +- .github/workflows/docker-buildx.yml | 26 +- .github/workflows/golangci-lint.yml | 2 +- .github/workflows/greetings.yml | 45 ++ .github/workflows/openimci.yml | 201 +++--- .github/workflows/release-drafter.yml | 55 ++ .github/workflows/release.yml | 7 +- .github/workflows/scripts-test.yml | 89 --- .github/workflows/sync.yml | 4 + .gitignore | 9 +- CHANGELOG/CHANGELOG-3.1.md | 87 +++ CHANGELOG/CHANGELOG.md | 61 ++ CONTRIBUTING.md | 4 + Dockerfile | 9 +- Makefile | 33 +- README-zh_CN.md | 348 ++++++---- README.md | 112 +-- assets/demo/hello-openim.png | Bin 0 -> 49844 bytes .goreleaser.yaml => build/goreleaser.yaml | 51 +- .../{docker => images}/openim-api/Dockerfile | 7 +- .../openim-cmdutils/Dockerfile | 4 +- .../openim-crontask/Dockerfile | 2 +- .../openim-msggateway/Dockerfile | 2 +- .../openim-msgtransfer/Dockerfile | 2 +- .../{docker => images}/openim-push/Dockerfile | 2 +- .../openim-rpc-auth/Dockerfile | 2 +- .../openim-rpc-conversation/Dockerfile | 2 +- .../openim-rpc-friend/Dockerfile | 2 +- .../openim-rpc-group/Dockerfile | 2 +- .../openim-rpc-msg/Dockerfile | 2 +- .../openim-rpc-third/Dockerfile | 2 +- .../openim-rpc-user/Dockerfile | 2 +- config/config-copy.yaml | 378 +++++++++++ config/config.yaml | 2 +- deployments/README.md | 1 - .../templates/env_template.yaml | 25 +- deployments/templates/init/README.md | 220 ++++++ deployments/templates/init/openim-api.service | 16 + .../templates/init/openim-cmdutils.service | 16 + .../templates/init/openim-crontask.service | 16 + .../templates/init/openim-msggateway.service | 15 + .../templates/init/openim-msgtransfer.service | 15 + .../templates/init/openim-push.service | 16 + deployments/templates/init/openim-rpc.service | 15 + deployments/templates/openim-api.yaml | 17 + deployments/templates/openim.yaml | 387 +++++++++++ docker-compose.yaml | 71 +- docs/.generated_docs | 4 - docs/CODEOWNERS | 7 +- docs/contrib/git_cherry-pick.md | 177 +++++ docs/contrib/init_config.md | 74 ++ docs/contrib/install_docker.md | 45 ++ docs/contrib/linux_development.md | 137 ++++ docs/contrib/local_actions.md | 14 + docs/contrib/protoc_tools.md | 60 ++ docs/contrib/util_go.md | 8 + docs/contrib/util_makefile.md | 90 +++ docs/contrib/util_scripts.md | 248 +++++++ docs/conversions/bash_log.md | 47 ++ .../cicd_actions.md} | 0 docs/conversions/go_code.md | 3 - go.work | 5 +- go.work.sum | 311 --------- install_guide.sh | 2 +- internal/api/user.go | 1 - internal/tools/msg_doc_convert.go | 14 + openim-chat/config/config.yaml | 104 --- openim-chat/scripts/admin_rpc_start.sh | 65 -- openim-chat/scripts/build.cmd | 14 - openim-chat/scripts/build_all_service.sh | 134 ---- openim-chat/scripts/check_all.sh | 49 -- openim-chat/scripts/docker_start_all.sh | 101 --- openim-chat/scripts/githooks/commit-msg | 93 --- openim-chat/scripts/githooks/pre-commit | 112 --- openim-chat/scripts/githooks/pre-push | 120 ---- openim-chat/scripts/path_info.sh | 80 --- openim-chat/scripts/start.bat | 5 - openim-chat/scripts/start_all.sh | 105 --- openim-chat/scripts/stop_all.sh | 47 -- openim-chat/scripts/style_info.sh | 66 -- pkg/apistruct/doc.go | 15 + pkg/authverify/doc.go | 15 + pkg/callbackstruct/doc.go | 15 + pkg/common/cmd/doc.go | 15 + pkg/common/config/doc.go | 15 + pkg/common/convert/doc.go | 15 + pkg/common/db/cache/doc.go | 15 + pkg/common/db/controller/doc.go | 15 + pkg/common/db/controller/user.go | 4 +- pkg/common/db/localcache/doc.go | 15 + pkg/common/db/relation/doc.go | 15 + pkg/common/db/s3/cont/doc.go | 15 + pkg/common/db/s3/cos/doc.go | 15 + pkg/common/db/s3/doc.go | 15 + pkg/common/db/s3/minio/doc.go | 15 + pkg/common/db/s3/minio/image.go | 14 + pkg/common/db/s3/minio/struct.go | 14 + pkg/common/db/s3/oss/doc.go | 15 + pkg/common/db/s3/oss/sign.go | 14 + pkg/common/db/table/relation/doc.go | 15 + pkg/common/db/table/unrelation/doc.go | 15 + pkg/common/db/unrelation/doc.go | 15 + pkg/common/db/unrelation/msg_convert.go | 14 + pkg/common/http/doc.go | 15 + pkg/common/kafka/doc.go | 15 + pkg/common/locker/doc.go | 15 + pkg/common/prome/doc.go | 15 + pkg/common/startrpc/doc.go | 15 + pkg/msgprocessor/doc.go | 15 + pkg/rpcclient/doc.go | 15 + pkg/rpcclient/notification/doc.go | 15 + pkg/statistics/doc.go | 15 + scripts/.spelling_failures | 6 + scripts/LICENSE/LICENSE | 201 ------ scripts/LICENSE/LICENSE_TEMPLATES | 13 - scripts/README.md | 209 +++++- scripts/advertise.sh | 44 +- scripts/batch_start_all.sh | 27 +- scripts/build-all-service.sh | 78 +++ scripts/build_all_service.sh | 151 ----- scripts/build_push_k8s_images.sh | 46 -- scripts/check-all.sh | 83 +++ scripts/check_all.sh | 80 --- scripts/cherry-pick.sh | 256 +++++++ scripts/common.sh | 3 +- scripts/demo.sh | 92 +++ ...eck_service.sh => docker-check-service.sh} | 21 +- .../docker-start-all.sh | 25 +- scripts/docker_start_all.sh | 60 -- scripts/enterprise/check_all.sh | 52 -- scripts/enterprise/path_info.cfg | 25 - scripts/env_check.sh | 3 +- scripts/environment.sh | 91 --- scripts/function.sh | 34 - scripts/gen-swagger-docs.sh | 73 ++ scripts/genconfig.sh | 22 +- scripts/gendoc.sh | 78 +++ scripts/githooks/pre-commit | 2 +- .golangci.yml => scripts/golangci.yml | 0 scripts/init-config.sh | 50 ++ scripts/init-env.sh | 31 + scripts/init_pwd.sh | 3 +- scripts/install-im-server.sh | 47 ++ scripts/install/README.md | 116 ++++ scripts/install/common.sh | 142 ++++ scripts/install/dependency.sh | 100 +++ scripts/install/environment.sh | 415 ++++++++++++ scripts/install/install-protobuf.sh | 116 ++++ scripts/install/install.sh | 149 ++++ scripts/install/openim-api.sh | 112 +++ scripts/install/openim-crontask.sh | 132 ++++ scripts/install/openim-man.sh | 96 +++ scripts/install/openim-msggateway.sh | 141 ++++ scripts/install/openim-msgtransfer.sh | 155 +++++ scripts/install/openim-push.sh | 153 +++++ scripts/install/openim-rpc.sh | 181 +++++ scripts/install/openim-tools.sh | 166 +++++ scripts/install/test.sh | 561 ++++++++++++++++ scripts/install/vimrc | 300 +++++++++ scripts/install_im_compose.sh | 140 ++-- scripts/install_im_server.sh | 85 --- scripts/lib/chat.sh | 178 +++++ scripts/lib/color.sh | 120 +++- scripts/lib/golang.sh | 131 +++- scripts/lib/init.sh | 183 ++++- scripts/lib/logging.sh | 82 ++- scripts/lib/release.sh | 14 +- scripts/lib/util.sh | 635 ++++++++++++++++-- scripts/lib/version.sh | 1 - .../function.sh => list-feature-tests.sh} | 25 +- scripts/make-rules/common.mk | 14 +- scripts/make-rules/copyright.mk | 2 +- scripts/make-rules/gen.mk | 17 + scripts/make-rules/golang.mk | 72 +- scripts/make-rules/image.mk | 47 +- scripts/msg_gateway_start.sh | 82 --- scripts/msg_transfer_start.sh | 72 -- scripts/path_info.sh | 141 ---- scripts/push_start.sh | 78 --- scripts/run-in-gopath.sh | 34 + scripts/start-all.sh | 74 ++ scripts/start_all.sh | 116 ---- scripts/start_component_check.sh | 42 -- scripts/start_cron.sh | 64 -- scripts/start_rpc_service.sh | 117 ---- scripts/stop-all.sh | 35 + scripts/stop_all.sh | 41 -- scripts/style_info.sh | 67 -- .../LICENSE => scripts/template}/LICENSE | 0 .../template}/LICENSE_TEMPLATES | 0 scripts/template/boilerplate.txt | 3 + scripts/template/footer.md.tmpl | 19 + scripts/template/head.md.tmpl | 31 + scripts/template/project_README.md | 41 ++ scripts/update-generated-docs.sh | 49 ++ scripts/update-yamlfmt.sh | 43 ++ scripts/verify-pkg-names.sh | 35 + scripts/verify-shellcheck.sh | 139 ++++ scripts/verify-spelling.sh | 41 ++ scripts/verify-typecheck.sh | 41 ++ scripts/verify-yamlfmt.sh | 48 ++ scripts/wait-for-it.sh | 48 +- test/README.md | 15 + test/jwt/main.go | 48 ++ test/testdata/README.md | 64 ++ test/testdata/db/messages.json | 0 test/testdata/db/users.json | 0 test/testdata/requests/login.json | 0 test/testdata/requests/register.json | 0 test/testdata/requests/sendMessage.json | 0 test/testdata/responses/login.json | 0 test/testdata/responses/register.json | 0 test/testdata/responses/sendMessage.json | 0 test/typecheck/README.md | 27 + test/typecheck/go.mod | 10 + test/typecheck/go.sum | 7 + test/typecheck/typecheck.go | 320 +++++++++ test/typecheck/typecheck_test.go | 121 ++++ test/wrktest.sh | 29 +- tools/README.md | 20 - tools/changelog/changelog.go | 308 +++++++++ tools/changelog/go.mod | 3 + tools/component/{main.go => component.go} | 114 ++-- tools/imctl/README.md | 47 ++ tools/imctl/cmd/genman/README.md | 49 ++ tools/imctl/cmd/genman/genman.go | 63 ++ tools/imctl/cmd/imctl/imctl.go | 29 + tools/imctl/go.mod | 19 + tools/imctl/go.sum | 26 + tools/imctl/internal/imctl/cmd/cmd.go | 133 ++++ tools/imctl/internal/imctl/cmd/profiling.go | 95 +++ .../imctl/util/interrupt/interrupt.go | 103 +++ .../imctl/util/templates/command_groups.go | 57 ++ .../internal/imctl/util/templates/markdown.go | 149 ++++ .../imctl/util/templates/normalizers.go | 99 +++ .../imctl/util/templates/templater.go | 296 ++++++++ .../imctl/util/templates/templates.go | 103 +++ .../imctl/internal/imctl/util/term/resize.go | 53 ++ tools/imctl/internal/imctl/util/term/term.go | 37 + .../internal/imctl/util/term/term_writer.go | 124 ++++ .../imctl/util/term/term_writer_test.go | 114 ++++ tools/infra/infra.go | 40 ++ tools/infra/main.go | 26 - tools/ncpu/README.md | 47 ++ tools/ncpu/main.go | 13 - tools/ncpu/ncpu.go | 27 + tools/ncpu/ncpu_test.go | 35 + tools/yamlfmt/OWNERS | 10 + tools/yamlfmt/go.mod | 8 + tools/yamlfmt/go.sum | 6 + tools/yamlfmt/yamlfmt.go | 72 ++ tools/yamlfmt/yamlfmt_test.go | 158 +++++ 255 files changed, 12457 insertions(+), 4111 deletions(-) create mode 100644 .github/release-drafter.yml create mode 100644 .github/workflows/greetings.yml create mode 100644 .github/workflows/release-drafter.yml delete mode 100644 .github/workflows/scripts-test.yml create mode 100644 CHANGELOG/CHANGELOG-3.1.md create mode 100644 assets/demo/hello-openim.png rename .goreleaser.yaml => build/goreleaser.yaml (78%) rename build/{docker => images}/openim-api/Dockerfile (85%) rename build/{docker => images}/openim-cmdutils/Dockerfile (86%) rename build/{docker => images}/openim-crontask/Dockerfile (93%) rename build/{docker => images}/openim-msggateway/Dockerfile (92%) rename build/{docker => images}/openim-msgtransfer/Dockerfile (94%) rename build/{docker => images}/openim-push/Dockerfile (93%) rename build/{docker => images}/openim-rpc-auth/Dockerfile (91%) rename build/{docker => images}/openim-rpc-conversation/Dockerfile (92%) rename build/{docker => images}/openim-rpc-friend/Dockerfile (92%) rename build/{docker => images}/openim-rpc-group/Dockerfile (92%) rename build/{docker => images}/openim-rpc-msg/Dockerfile (92%) rename build/{docker => images}/openim-rpc-third/Dockerfile (93%) rename build/{docker => images}/openim-rpc-user/Dockerfile (93%) create mode 100644 config/config-copy.yaml rename openim-chat/scripts/function.sh => deployments/templates/env_template.yaml (58%) create mode 100644 deployments/templates/init/README.md create mode 100644 deployments/templates/init/openim-api.service create mode 100644 deployments/templates/init/openim-cmdutils.service create mode 100644 deployments/templates/init/openim-crontask.service create mode 100644 deployments/templates/init/openim-msggateway.service create mode 100644 deployments/templates/init/openim-msgtransfer.service create mode 100644 deployments/templates/init/openim-push.service create mode 100644 deployments/templates/init/openim-rpc.service create mode 100644 deployments/templates/openim-api.yaml create mode 100644 deployments/templates/openim.yaml create mode 100644 docs/contrib/git_cherry-pick.md create mode 100644 docs/contrib/init_config.md create mode 100644 docs/contrib/install_docker.md create mode 100644 docs/contrib/linux_development.md create mode 100644 docs/contrib/local_actions.md create mode 100644 docs/contrib/protoc_tools.md create mode 100644 docs/contrib/util_go.md create mode 100644 docs/contrib/util_makefile.md create mode 100644 docs/contrib/util_scripts.md create mode 100644 docs/conversions/bash_log.md rename docs/{contrib/cicd-actions.md => conversions/cicd_actions.md} (100%) delete mode 100644 go.work.sum delete mode 100644 openim-chat/config/config.yaml delete mode 100644 openim-chat/scripts/admin_rpc_start.sh delete mode 100644 openim-chat/scripts/build.cmd delete mode 100644 openim-chat/scripts/build_all_service.sh delete mode 100644 openim-chat/scripts/check_all.sh delete mode 100644 openim-chat/scripts/docker_start_all.sh delete mode 100644 openim-chat/scripts/githooks/commit-msg delete mode 100644 openim-chat/scripts/githooks/pre-commit delete mode 100644 openim-chat/scripts/githooks/pre-push delete mode 100644 openim-chat/scripts/path_info.sh delete mode 100644 openim-chat/scripts/start.bat delete mode 100644 openim-chat/scripts/start_all.sh delete mode 100644 openim-chat/scripts/stop_all.sh delete mode 100644 openim-chat/scripts/style_info.sh create mode 100644 pkg/apistruct/doc.go create mode 100644 pkg/authverify/doc.go create mode 100644 pkg/callbackstruct/doc.go create mode 100644 pkg/common/cmd/doc.go create mode 100644 pkg/common/config/doc.go create mode 100644 pkg/common/convert/doc.go create mode 100644 pkg/common/db/cache/doc.go create mode 100644 pkg/common/db/controller/doc.go create mode 100644 pkg/common/db/localcache/doc.go create mode 100644 pkg/common/db/relation/doc.go create mode 100644 pkg/common/db/s3/cont/doc.go create mode 100644 pkg/common/db/s3/cos/doc.go create mode 100644 pkg/common/db/s3/doc.go create mode 100644 pkg/common/db/s3/minio/doc.go create mode 100644 pkg/common/db/s3/oss/doc.go create mode 100644 pkg/common/db/table/relation/doc.go create mode 100644 pkg/common/db/table/unrelation/doc.go create mode 100644 pkg/common/db/unrelation/doc.go create mode 100644 pkg/common/http/doc.go create mode 100644 pkg/common/kafka/doc.go create mode 100644 pkg/common/locker/doc.go create mode 100644 pkg/common/prome/doc.go create mode 100644 pkg/common/startrpc/doc.go create mode 100644 pkg/msgprocessor/doc.go create mode 100644 pkg/rpcclient/doc.go create mode 100644 pkg/rpcclient/notification/doc.go create mode 100644 pkg/statistics/doc.go create mode 100644 scripts/.spelling_failures delete mode 100644 scripts/LICENSE/LICENSE delete mode 100644 scripts/LICENSE/LICENSE_TEMPLATES create mode 100755 scripts/build-all-service.sh delete mode 100755 scripts/build_all_service.sh delete mode 100755 scripts/build_push_k8s_images.sh create mode 100755 scripts/check-all.sh delete mode 100755 scripts/check_all.sh create mode 100755 scripts/cherry-pick.sh create mode 100755 scripts/demo.sh rename scripts/{docker_check_service.sh => docker-check-service.sh} (80%) rename openim-chat/scripts/build_docker.sh => scripts/docker-start-all.sh (54%) mode change 100644 => 100755 delete mode 100755 scripts/docker_start_all.sh delete mode 100755 scripts/enterprise/check_all.sh delete mode 100644 scripts/enterprise/path_info.cfg delete mode 100755 scripts/environment.sh delete mode 100755 scripts/function.sh create mode 100755 scripts/gen-swagger-docs.sh create mode 100755 scripts/gendoc.sh rename .golangci.yml => scripts/golangci.yml (100%) create mode 100755 scripts/init-config.sh create mode 100755 scripts/init-env.sh create mode 100755 scripts/install-im-server.sh create mode 100644 scripts/install/README.md create mode 100755 scripts/install/common.sh create mode 100755 scripts/install/dependency.sh create mode 100755 scripts/install/environment.sh create mode 100755 scripts/install/install-protobuf.sh create mode 100755 scripts/install/install.sh create mode 100755 scripts/install/openim-api.sh create mode 100755 scripts/install/openim-crontask.sh create mode 100755 scripts/install/openim-man.sh create mode 100755 scripts/install/openim-msggateway.sh create mode 100755 scripts/install/openim-msgtransfer.sh create mode 100755 scripts/install/openim-push.sh create mode 100755 scripts/install/openim-rpc.sh create mode 100755 scripts/install/openim-tools.sh create mode 100755 scripts/install/test.sh create mode 100644 scripts/install/vimrc delete mode 100755 scripts/install_im_server.sh create mode 100755 scripts/lib/chat.sh rename scripts/{enterprise/function.sh => list-feature-tests.sh} (67%) delete mode 100755 scripts/msg_gateway_start.sh delete mode 100755 scripts/msg_transfer_start.sh delete mode 100755 scripts/path_info.sh delete mode 100755 scripts/push_start.sh create mode 100755 scripts/run-in-gopath.sh create mode 100755 scripts/start-all.sh delete mode 100755 scripts/start_all.sh delete mode 100644 scripts/start_component_check.sh delete mode 100755 scripts/start_cron.sh delete mode 100755 scripts/start_rpc_service.sh create mode 100755 scripts/stop-all.sh delete mode 100755 scripts/stop_all.sh delete mode 100755 scripts/style_info.sh rename {openim-chat/scripts/LICENSE => scripts/template}/LICENSE (100%) rename {openim-chat/scripts/LICENSE => scripts/template}/LICENSE_TEMPLATES (100%) create mode 100644 scripts/template/boilerplate.txt create mode 100644 scripts/template/footer.md.tmpl create mode 100644 scripts/template/head.md.tmpl create mode 100644 scripts/template/project_README.md create mode 100755 scripts/update-generated-docs.sh create mode 100755 scripts/update-yamlfmt.sh create mode 100755 scripts/verify-pkg-names.sh create mode 100755 scripts/verify-shellcheck.sh create mode 100755 scripts/verify-spelling.sh create mode 100755 scripts/verify-typecheck.sh create mode 100755 scripts/verify-yamlfmt.sh create mode 100644 test/README.md create mode 100644 test/jwt/main.go create mode 100644 test/testdata/README.md create mode 100644 test/testdata/db/messages.json create mode 100644 test/testdata/db/users.json create mode 100644 test/testdata/requests/login.json create mode 100644 test/testdata/requests/register.json create mode 100644 test/testdata/requests/sendMessage.json create mode 100644 test/testdata/responses/login.json create mode 100644 test/testdata/responses/register.json create mode 100644 test/testdata/responses/sendMessage.json create mode 100644 test/typecheck/README.md create mode 100644 test/typecheck/go.mod create mode 100644 test/typecheck/go.sum create mode 100644 test/typecheck/typecheck.go create mode 100644 test/typecheck/typecheck_test.go create mode 100644 tools/changelog/changelog.go create mode 100644 tools/changelog/go.mod rename tools/component/{main.go => component.go} (71%) create mode 100644 tools/imctl/README.md create mode 100644 tools/imctl/cmd/genman/README.md create mode 100644 tools/imctl/cmd/genman/genman.go create mode 100644 tools/imctl/cmd/imctl/imctl.go create mode 100644 tools/imctl/go.mod create mode 100644 tools/imctl/go.sum create mode 100644 tools/imctl/internal/imctl/cmd/cmd.go create mode 100644 tools/imctl/internal/imctl/cmd/profiling.go create mode 100644 tools/imctl/internal/imctl/util/interrupt/interrupt.go create mode 100644 tools/imctl/internal/imctl/util/templates/command_groups.go create mode 100644 tools/imctl/internal/imctl/util/templates/markdown.go create mode 100644 tools/imctl/internal/imctl/util/templates/normalizers.go create mode 100644 tools/imctl/internal/imctl/util/templates/templater.go create mode 100644 tools/imctl/internal/imctl/util/templates/templates.go create mode 100644 tools/imctl/internal/imctl/util/term/resize.go create mode 100644 tools/imctl/internal/imctl/util/term/term.go create mode 100644 tools/imctl/internal/imctl/util/term/term_writer.go create mode 100644 tools/imctl/internal/imctl/util/term/term_writer_test.go create mode 100644 tools/infra/infra.go delete mode 100644 tools/infra/main.go create mode 100644 tools/ncpu/README.md delete mode 100644 tools/ncpu/main.go create mode 100644 tools/ncpu/ncpu.go create mode 100644 tools/ncpu/ncpu_test.go create mode 100644 tools/yamlfmt/OWNERS create mode 100644 tools/yamlfmt/go.mod create mode 100644 tools/yamlfmt/go.sum create mode 100644 tools/yamlfmt/yamlfmt.go create mode 100644 tools/yamlfmt/yamlfmt_test.go diff --git a/.dockerignore b/.dockerignore index 9faeff616..8e6a7c121 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,4 @@ -# Ignore files and directories starting with a dot + diff --git a/.env b/.env index 412b75076..a4b5aaabc 100644 --- a/.env +++ b/.env @@ -1,5 +1,5 @@ USER=root PASSWORD=openIM123 MINIO_ENDPOINT=http://127.0.0.1:10005 -API_URL=http://127.0.0.1:10002/object/ -DATA_DIR=./ \ No newline at end of file +API_URL=http://127.0.0.1:10002 +DATA_DIR=./ diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 000000000..154386ff5 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,51 @@ +# 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-template: 'v$RESOLVED_VERSION 🌈' +tag-template: 'v$RESOLVED_VERSION' +categories: + - title: '🚀 Features' + labels: + - 'feature' + - 'enhancement' + - title: '🐛 Bug Fixes' + labels: + - 'kind/fix' + - 'kind/feature' + - 'enhancement' + - 'kind/documentation' + - 'good first issue' + - title: '🧰 Maintenance' + label: 'chore' +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. +version-resolver: + major: + labels: + - 'major' + minor: + labels: + - 'minor' + patch: + labels: + - 'patch' + default: patch +template: | + ## Changes $PREVIOUS_TAG + + $CHANGES + + ## Contributors to this $REPOSITORY release + + $CONTRIBUTORS \ No newline at end of file diff --git a/.github/sync.yml b/.github/sync.yml index 12b1c021f..6aa6dd566 100644 --- a/.github/sync.yml +++ b/.github/sync.yml @@ -97,7 +97,7 @@ group: OpenIMSDK/community OpenIMSDK/openim-charts OpenIMSDK/openim-sdk-cpp@main - files: + files: - source: LICENSE dest: LICENSE replace: false diff --git a/.github/workflows/docker-buildx.yml b/.github/workflows/docker-buildx.yml index 3d1b3015f..6ca47e924 100644 --- a/.github/workflows/docker-buildx.yml +++ b/.github/workflows/docker-buildx.yml @@ -95,7 +95,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: ./build/docker/openim-api/Dockerfile + file: ./build/images/openim-api/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta1.outputs.tags }} @@ -113,7 +113,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: ./build/docker/openim-cmdutils/Dockerfile + file: ./build/images/openim-cmdutils/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta2.outputs.tags }} @@ -131,7 +131,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: ./build/docker/openim-crontask/Dockerfile + file: ./build/images/openim-crontask/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta3.outputs.tags }} @@ -149,7 +149,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: ./build/docker/openim-msggateway/Dockerfile + file: ./build/images/openim-msggateway/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta4.outputs.tags }} @@ -167,7 +167,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: ./build/docker/openim-msgtransfer/Dockerfile + file: ./build/images/openim-msgtransfer/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta5.outputs.tags }} @@ -185,7 +185,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: ./build/docker/openim-push/Dockerfile + file: ./build/images/openim-push/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta6.outputs.tags }} @@ -203,7 +203,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: ./build/docker/openim-rpc-auth/Dockerfile + file: ./build/images/openim-rpc-auth/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta7.outputs.tags }} @@ -221,7 +221,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: ./build/docker/openim-rpc-conversation/Dockerfile + file: ./build/images/openim-rpc-conversation/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta8.outputs.tags }} @@ -239,7 +239,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: ./build/docker/openim-rpc-friend/Dockerfile + file: ./build/images/openim-rpc-friend/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta9.outputs.tags }} @@ -257,7 +257,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: ./build/docker/openim-rpc-group/Dockerfile + file: ./build/images/openim-rpc-group/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta10.outputs.tags }} @@ -275,7 +275,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: ./build/docker/openim-rpc-msg/Dockerfile + file: ./build/images/openim-rpc-msg/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta11.outputs.tags }} @@ -293,7 +293,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: ./build/docker/openim-rpc-third/Dockerfile + file: ./build/images/openim-rpc-third/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta12.outputs.tags }} @@ -311,7 +311,7 @@ jobs: uses: docker/build-push-action@v4 with: context: . - file: ./build/docker/openim-rpc-user/Dockerfile + file: ./build/images/openim-rpc-user/Dockerfile platforms: linux/amd64,linux/arm64 push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta13.outputs.tags }} diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index adf33d8d4..ba600f1f7 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -42,7 +42,7 @@ jobs: # # 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=/my/path/.golangci.yml --issues-exit-code=0 + 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 diff --git a/.github/workflows/greetings.yml b/.github/workflows/greetings.yml new file mode 100644 index 000000000..47a58d2b6 --- /dev/null +++ b/.github/workflows/greetings.yml @@ -0,0 +1,45 @@ +# 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: first-interaction + +on: + issues: + types: [opened] + pull_request: + branches: [main] + types: [opened] + +jobs: + check_for_first_interaction: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/first-interaction@main + with: + repo-token: ${{ secrets.BOT_GITHUB_TOKEN }} + issue-message: | + Hello! Thank you for filing an issue. + + If this is a bug report, please include relevant logs to help us debug the problem. + + [Join slack 🤖](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) to connect and communicate with our developers. + pr-message: | + Hello! Thank you for your contribution. + + If you are fixing a bug, please reference the issue number in the description. + + If you are implementing a feature request, please check with the maintainers that the feature will be accepted first. + + [Join slack 🤖](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) to connect and communicate with our developers. \ No newline at end of file diff --git a/.github/workflows/openimci.yml b/.github/workflows/openimci.yml index d172eb251..54c30e4d8 100644 --- a/.github/workflows/openimci.yml +++ b/.github/workflows/openimci.yml @@ -36,124 +36,99 @@ env: GO_VERSION: "1.19" GOLANGCI_VERSION: "v1.50.1" + jobs: openim: name: Test with go ${{ matrix.go_version }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} permissions: - # Give the default GITHUB_TOKEN write permission to commit and push the changed files back to the repository. contents: write environment: name: openim strategy: matrix: - go_version: ["1.18","1.19","1.20"] + go_version: ["1.18","1.19","1.20","1.21"] os: [ubuntu-latest] steps: - - name: Set up Go ${{ matrix.go_version }} - uses: actions/setup-go@v4 - with: - go-version: ${{ matrix.go_version }} - id: go + - name: Setup + uses: actions/checkout@v3 + + - name: Set up Go ${{ matrix.go_version }} + uses: actions/setup-go@v4 + with: + go-version: ${{ matrix.go_version }} + id: go - - name: Check out code into the Go module directory - uses: actions/checkout@v3 + - name: Install Task + uses: arduino/setup-task@v1 + with: + version: 2.x - - name: Install Task - uses: arduino/setup-task@v1 - with: - version: 2.x + - name: Module Operations + run: | + sudo make tidy + sudo make tools.verify.go-gitlint - - name: Run go modules tidy - run: | - sudo make tidy - sudo make tools.verify.go-gitlint - echo "Run go modules tidy successfully" + - name: Format Code + run: sudo make format + continue-on-error: true - - name: Run go format - run: | - sudo make format - echo "Run go format successfully" - continue-on-error: true + - name: Generate Files + run: make gen + continue-on-error: true - - name: Generate all necessary files, such as error code files - run: | - make generate - echo "Generate all necessary files successfully" - continue-on-error: true + - name: Build Source + run: sudo make build - - name: Run unit test and get test coverage - run: | - make cover - echo "Run unit test and get test coverage successfully" - continue-on-error: true + - name: Cleanup Build + run: sudo make clean - - name: Build source code for host platform - run: | - sudo make build - echo "Build source code for host platform successfully" + - name: Push Changes to Main + uses: stefanzweifel/git-auto-commit-action@v4 + with: + commit_message: "cicd: robot automated Change" + branch: main + continue-on-error: true - - name: OpenIM verify copyright - run: | - sudo make verify-copyright - sudo make add-copyright - echo "OpenIM verify successfully" - continue-on-error: true + - name: Set Current Directory + id: set_directory + run: echo "::set-output name=directory::$(pwd)" + continue-on-error: true - - name: Clean all build - run: | - sudo make clean - echo "Clean all build successfully" - - - name: push OpenIM - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: "cicd: robot automated Change" - # commit_options: '--no-verify --signoff' - branch: main - # create_branch: true - # # Optional commit user and author settings - # commit_user_name: kubbot # defaults to "github-actions[bot]" - # commit_user_email: 3293172751ysy@gmail.com # defaults to "41898282+github-actions[bot]@users.noreply.github.com" - # commit_author: Kubbot # defaults to author of the commit that triggered the run - continue-on-error: true - - - name: Commit Changes - uses: stefanzweifel/git-auto-commit-action@v4 - with: - commit_message: "chore(fmt): robot automated format and lint Change" - commit_options: '--no-verify --signoff' - branch: main - continue-on-error: true - - - name: Set Current Directory - id: set_directory - run: | - echo "::set-output name=directory::$(pwd)" - continue-on-error: true - - - name: Collect Test Coverage File - id: collect_coverage - run: | - cd ${{ steps.set_directory.outputs.directory }} - make cover - echo "::set-output name=coverage_file::./_output/tmp/coverage.out" - continue-on-error: true - - - name: Display Test Coverage - run: | - echo "Test Coverage:" - cat ${{ steps.collect_coverage.outputs.coverage_file }} - continue-on-error: true - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - 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: Teat OpenIM make install start on ${{ matrix.os }} + name: Test OpenIM install/start on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + environment: + name: openim + strategy: + matrix: + go_version: ["1.21"] + os: ["ubuntu-latest"] + steps: + - name: Checkout and Install OpenIM + uses: actions/checkout@v3 + - name: Install Task + uses: arduino/setup-task@v1 + with: + version: 2.x + - name: Run OpenIM make install start + run: | + sudo make install + + execute-scripts: + name: Execute OpenIM script on ${{ matrix.os }} runs-on: ${{ matrix.os }} environment: name: openim @@ -162,15 +137,35 @@ jobs: go_version: ["1.20"] os: ["ubuntu-latest"] steps: - - name: Set up Go ${{ matrix.go_version }} - uses: actions/setup-go@v4 - with: - go-version: ${{ matrix.go_version }} - id: go + - name: Checkout code + uses: actions/checkout@v3 - - name: Check out code into the Go module directory - uses: actions/checkout@v3 + - name: Set up Go ${{ matrix.go_version }} + uses: actions/setup-go@v4 + with: + go-version: ${{ matrix.go_version }} + id: go + - name: Install Task + uses: arduino/setup-task@v1 + with: + version: 2.x + - name: Docker Operations + run: | + curl -o docker-compose.yaml https://gist.githubusercontent.com/cubxxw/b1d5cbd2edfa23fee911118aa3e8249e/raw/openim-server.sh + sudo docker compose up -d + sudo sleep 60 - - name: Run OpenIM make install start - run: | - sudo make install \ No newline at end of file + - name: Module Operations + run: | + sudo make tidy + sudo make tools.verify.go-gitlint + + - name: Build, Start and Check Services + run: | + make build + make start + make check + + - name: Print OpenIM Logs + run: sudo cat ./_output/logs/* 2>/dev/null + continue-on-error: true diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml new file mode 100644 index 000000000..0b014990e --- /dev/null +++ b/.github/workflows/release-drafter.yml @@ -0,0 +1,55 @@ +# 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: Release Drafter + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - master + # pull_request event is required only for autolabeler + pull_request: + # Only following types are handled by the action, but one can default to all as well + types: [opened, reopened, synchronize] + # pull_request_target event is required for autolabeler to support PRs from forks + # pull_request_target: + # types: [opened, reopened, synchronize] + +permissions: + contents: read + +jobs: + update_release_draft: + permissions: + # write permission is required to create a github release + contents: write + # write permission is required for autolabeler + # otherwise, read permission is required at least + pull-requests: write + runs-on: ubuntu-latest + steps: + # (Optional) GitHub Enterprise requires GHE_HOST variable set + #- name: Set GHE_HOST + # run: | + # echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV + + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: release-drafter/release-drafter@v5 + # (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml + # with: + # config-name: my-config.yml + # disable-autolabeler: true + env: + GITHUB_TOKEN: ${{ secrets.REDBOT_GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fd019c4df..62b89e837 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -name: OpenIM Server Release +name: OpenIM Server Release Workflow on: push: @@ -43,9 +43,12 @@ jobs: # either 'goreleaser' (default) or 'goreleaser-pro': distribution: goreleaser version: latest - args: release --clean + workdir: . + args: release -f ./build/goreleaser.yaml --rm-dist --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 }} diff --git a/.github/workflows/scripts-test.yml b/.github/workflows/scripts-test.yml deleted file mode 100644 index 44b217c59..000000000 --- a/.github/workflows/scripts-test.yml +++ /dev/null @@ -1,89 +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 Start Execute Scripts - -on: - push: - branches: - - main - paths-ignore: - - "docs/**" - - "README.md" - - "README_zh-CN.md" - - "CONTRIBUTING.md" - pull_request: - branches: - - main - paths-ignore: - - "README.md" - - "README_zh-CN.md" - - "CONTRIBUTING.md" - - "docs/**" - -jobs: - execute-scripts: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Download Docker Compose - run: | - curl -o docker-compose.yaml https://gist.githubusercontent.com/cubxxw/b1d5cbd2edfa23fee911118aa3e8249e/raw/openim-server.sh - shell: bash - - - name: Start Docker Compose - run: | - sudo docker compose up -d - sudo sleep 60 - continue-on-error: true - - - name: Stop all services - run: | - sudo chmod +x ./scripts/stop_all.sh - sudo ./scripts/stop_all.sh - sudo cat logs/openIM.log 2>/dev/null - shell: bash - continue-on-error: true - - - name: Build all services - run: | - sudo chmod +x ./scripts/build_all_service.sh - sudo ./scripts/build_all_service.sh - sudo cat logs/openIM.log 2>/dev/null - shell: bash - - - name: Start all services - run: | - sudo chmod +x ./scripts/start_all.sh - sudo ./scripts/start_all.sh - sudo cat logs/openIM.log 2>/dev/null - continue-on-error: true - shell: bash - - - name: Check all services - run: | - sudo chmod +x ./scripts/check_all.sh - sudo ./scripts/check_all.sh - sudo cat logs/openIM.log 2>/dev/null - shell: bash - - - name: Print openIM.log - run: | - sudo cat logs/* 2>/dev/null - sudo cat logs/* 2>/dev/null >> "$GITHUB_OUTPUT" - shell: bash - continue-on-error: true diff --git a/.github/workflows/sync.yml b/.github/workflows/sync.yml index d6e15bf23..b9e67d438 100644 --- a/.github/workflows/sync.yml +++ b/.github/workflows/sync.yml @@ -6,6 +6,10 @@ name: Synchronize kubecub public code to other repositories on: push: + paths: + - scripts/* + - docs/* + - config/* branches: - main workflow_dispatch: diff --git a/.gitignore b/.gitignore index bb9e8e8c0..97d62f5fe 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,12 @@ bin/ output/ _output/ +### OpenIM Config ### +config/config.yaml +./config/config.yaml +.env +./.env + ### OpenIM deploy ### deploy/openim_demo deploy/openim-api @@ -153,10 +159,11 @@ flycheck_*.el *.out # Dependency directories (remove the comment below to include it) -# vendor/ +vendor/ # Go workspace file # go.work +go.work.sum ### JetBrains ### # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider diff --git a/CHANGELOG/CHANGELOG-3.1.md b/CHANGELOG/CHANGELOG-3.1.md new file mode 100644 index 000000000..c51eb2098 --- /dev/null +++ b/CHANGELOG/CHANGELOG-3.1.md @@ -0,0 +1,87 @@ +# Version logging for OpenIM + + + +- [Version logging for OpenIM](#version-logging-for-openim) + - [Unreleased](#unreleased) + - [v3.1.2-beta.3 - 2023-08-09](#v312-beta3---2023-08-09) + - [v3.1.2-beta.2 - 2023-08-09](#v312-beta2---2023-08-09) + - [v3.1.2-beta.1 - 2023-08-09](#v312-beta1---2023-08-09) + - [v3.1.2-beta.0 - 2023-08-08](#v312-beta0---2023-08-08) + - [v3.1.2.beta.0 - 2023-08-08](#v312beta0---2023-08-08) + - [v3.1.1-beta.4 - 2023-08-07](#v311-beta4---2023-08-07) + - [v3.1.1-beta.3 - 2023-08-05](#v311-beta3---2023-08-05) + - [v3.1.1-beta.2 - 2023-08-04](#v311-beta2---2023-08-04) + - [v3.1.1-beta.1 - 2023-08-04](#v311-beta1---2023-08-04) + - [v3.1.1-alpha.3 - 2023-08-03](#v311-alpha3---2023-08-03) + - [v3.1.1-alpha.2 - 2023-08-03](#v311-alpha2---2023-08-03) + - [v3.1.1-alpha.1 - 2023-08-02](#v311-alpha1---2023-08-02) + - [v3.1.0 - 2023-07-28](#v310---2023-07-28) + - [Reverts](#reverts) + - [Pull Requests](#pull-requests) + + + + + +## [Unreleased] + + + +## [v3.1.2-beta.3] - 2023-08-09 + + +## [v3.1.2-beta.2] - 2023-08-09 + + +## [v3.1.2-beta.1] - 2023-08-09 + + +## [v3.1.2-beta.0] - 2023-08-08 + + +## [v3.1.2.beta.0] - 2023-08-08 + + +## [v3.1.1-beta.4] - 2023-08-07 + + +## [v3.1.1-beta.3] - 2023-08-05 + + +## [v3.1.1-beta.2] - 2023-08-04 + + +## [v3.1.1-beta.1] - 2023-08-04 + + +## [v3.1.1-alpha.3] - 2023-08-03 + + +## [v3.1.1-alpha.2] - 2023-08-03 + + +## [v3.1.1-alpha.1] - 2023-08-02 + + +## v3.1.0 - 2023-07-28 +### Reverts +- update etcd to v3.5.2 ([#206](https://github.com/OpenIMSDK/Open-IM-Server/issues/206)) + +### Pull Requests +- Merge branch 'tuoyun' + + +[Unreleased]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.2-beta.3...HEAD +[v3.1.2-beta.3]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.2-beta.2...v3.1.2-beta.3 +[v3.1.2-beta.2]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.2-beta.1...v3.1.2-beta.2 +[v3.1.2-beta.1]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.2-beta.0...v3.1.2-beta.1 +[v3.1.2-beta.0]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.2.beta.0...v3.1.2-beta.0 +[v3.1.2.beta.0]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-beta.4...v3.1.2.beta.0 +[v3.1.1-beta.4]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-beta.3...v3.1.1-beta.4 +[v3.1.1-beta.3]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-beta.2...v3.1.1-beta.3 +[v3.1.1-beta.2]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-beta.1...v3.1.1-beta.2 +[v3.1.1-beta.1]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-alpha.3...v3.1.1-beta.1 +[v3.1.1-alpha.3]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-alpha.2...v3.1.1-alpha.3 +[v3.1.1-alpha.2]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.1-alpha.1...v3.1.1-alpha.2 +[v3.1.1-alpha.1]: https://github.com/OpenIMSDK/Open-IM-Server/compare/v3.1.0...v3.1.1-alpha.1 diff --git a/CHANGELOG/CHANGELOG.md b/CHANGELOG/CHANGELOG.md index 822e9bc92..6ca4d08b2 100644 --- a/CHANGELOG/CHANGELOG.md +++ b/CHANGELOG/CHANGELOG.md @@ -3,6 +3,8 @@ - [Changelog](#changelog) - [OpenIM versioning policy](#openim-versioning-policy) - [command](#command) + - [install](#install) + - [User](#user) - [create next tag](#create-next-tag) - [Release version logs](#release-version-logs) - [Introduction](#introduction) @@ -22,10 +24,68 @@ All notable changes to this project will be documented in this file. ## command +To use git-chglog you need to configure: + +1. CHANGELOG templates +2. git-chglog configuration + +### install + +```bash +$ go get github.com/git-chglog/git-chglog/cmd/git-chglog +``` + + +## User + +```bash +$ git-chglog --init +``` + +**Options** + +- What is the URL of your repository?: https://github.com/OpenIMSDK/Open-IM-Server +- What is your favorite style?: github +- Choose the format of your favorite commit message: (): -- feat(core): Add new feature +- What is your favorite template style?: standard +- Do you include Merge Commit in CHANGELOG?: n +- Do you include Revert Commit in CHANGELOG?: y +- In which directory do you output configuration files and templates?: .chglog + ```bash git-chglog --tag-filter-pattern 'v2.0.*' -o CHANGELOG-2.0.md ``` +**Other uses:** + +```bash +$ git-chglog + + If is not specified, it corresponds to all tags. + This is the simplest example. + +$ git-chglog 1.0.0..2.0.0 + + The above is a command to generate CHANGELOG including commit of 1.0.0 to 2.0.0. + +$ git-chglog 1.0.0 + + The above is a command to generate CHANGELOG including commit of only 1.0.0. + +$ git-chglog $(git describe --tags $(git rev-list --tags --max-count=1)) + + The above is a command to generate CHANGELOG with the commit included in the latest tag. + +$ git-chglog --output CHANGELOG.md + + The above is a command to output to CHANGELOG.md instead of standard output. + +$ git-chglog --config custom/dir/config.yml + + The above is a command that uses a configuration file placed other than ".chglog/config.yml". +``` + + ## create next tag ```bash @@ -51,6 +111,7 @@ git tag 2.0.0 + [OpenIM CHANGELOG-V2.3](CHANGELOG-2.3.md) + [OpenIM CHANGELOG-V2.9](CHANGELOG-2.9.md) + [OpenIM CHANGELOG-V3.0](CHANGELOG-3.0.md) ++ [OpenIM CHANGELOG-V3.1](CHANGELOG-3.1.md) ## Introduction diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 85f92bb36..59c0c47db 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,10 @@ So, you want to hack on Open-IM-Server? Yay! First of all, thank you for considering contributing to our project! We appreciate your time and effort, and we value any contribution, whether it's reporting a bug, suggesting a new feature, or submitting a pull request. +![Hello OpenIM Image](assets/demo/hello-openim.png) + +> Use `make demo` start contributing fast. + This document provides guidelines and best practices to help you contribute effectively. ## 📇Topics diff --git a/Dockerfile b/Dockerfile index 321f8b03d..ff5a3763e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ ENV GOPROXY=$GOPROXY # Set up the working directory WORKDIR /openim/openim-server -COPY go.mod go.sum go.work go.work.sum ./ +COPY go.mod go.sum go.work ./ #RUN go mod download # Copy all files to the container @@ -19,14 +19,13 @@ ADD . . RUN make clean RUN make build -FROM ghcr.io/openim-sigs/openim-bash-image:latest +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}/_output/bin/platforms /openim/openim-server/_output/bin/platforms -COPY --from=builder ${SERVER_WORKDIR}/_output/bin-tools/platforms /openim/openim-server/_output/bin-tools/platforms -CMD ["bash","-c","${OPENIM_SERVER_CMDDIR}/docker_start_all.sh"] +CMD ["/openim/openim-server/scripts/docker-start-all.sh"] diff --git a/Makefile b/Makefile index de6570dd9..7179ed8ec 100644 --- a/Makefile +++ b/Makefile @@ -6,13 +6,13 @@ ## all: Run tidy, gen, add-copyright, format, lint, cover, build ✨ .PHONY: all -all: tidy gen add-copyright format lint cover build +all: tidy gen add-copyright lint cover restart # ============================================================================== # Build set ROOT_PACKAGE=github.com/OpenIMSDK/Open-IM-Server -# TODO: This is version control for the future +# TODO: This is version control for the future https://github.com/OpenIMSDK/Open-IM-Server/issues/574 VERSION_PACKAGE=github.com/OpenIMSDK/Open-IM-Server/pkg/version # ============================================================================== @@ -53,16 +53,45 @@ export USAGE_OPTIONS # ============================================================================== # Targets +## init: Initialize openim server project ✨ +.PHONY: init +init: + @$(MAKE) gen.init + +## demo: Run demo get started with Makefiles quickly ✨ +.PHONY: demo +demo: + @$(MAKE) go.demo + ## build: Build binaries by default ✨ .PHONY: build build: @$(MAKE) go.build +## start: Start openim ✨ +.PHONY: start +start: + @$(MAKE) go.start + +## stop: Stop openim ✨ +.PHONY: stop +stop: + @$(MAKE) go.stop + +## restart: Restart openim ✨ +.PHONY: restart +restart: clean stop build start + ## multiarch: Build binaries for multiple platforms. See option PLATFORMS. ✨ .PHONY: multiarch multiarch: @$(MAKE) go.build.multiarch +## verify: execute all verity scripts. ✨ +.PHONY: verify +verify: + @$(MAKE) go.verify + ## install: Install deployment openim ✨ .PHONY: install install: diff --git a/README-zh_CN.md b/README-zh_CN.md index b9b58deec..3180b91f4 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -1,16 +1,19 @@ -

- - Open IM Server
-
- ⭐️ Open source Instant Messaging Server ⭐️
-

+

+ + + +

+ +

+ ⭐️ Open source Instant Messaging Server ⭐️
+

A+ good first - +

@@ -18,164 +21,220 @@

- English • - 中文 + English • + 简体中文 • + Docs

+

-## Open-IM-Server 是什么 +## ✨ 关于 OpenIM -Open-IM-Server 是一款即时通讯服务器,使用纯 Golang 开发,采用 JSON over WebSocket 传输协议。在 Open-IM-Server 中,所有东西都是消息,因此您可以轻松扩展自定义消息,而无需修改服务器代码。使用微服务架构,Open-IM-Server 可以使用集群进行部署。通过在服务器上部署 Open-IM-Server,开发人员可以快速地将即时通讯和实时网络功能集成到自己的应用程序中,并确保业务数据的安全性和隐私性。 +Open-IM-Server 是使用纯 Golang 精心制作的强大的即时消息服务器。其通过 JSON over WebSocket 进行通信的独特方法将每次交互都视为消息。这简化了定制并消除了修改服务器代码的需求。通过利用微服务架构,服务器可以通过集群部署,保证出色的性能和可伸缩性。 -Open-IM-Server并不是一个独立的产品,本身不包含账号的注册和登录服务。 -为方便大家测试,我们开源了包括登录注册功能的 [chat 仓库](https://github.com/OpenIMSDK/chat),chat 业务服务端和 Open-IM-Server 一起部署,即可搭建一个聊天产品。 +Open-IM-Server 不仅仅是一个即时消息服务器;它是将实时网络集成到您的应用程序中的强大工具,定位为您集成的首选选择!🚀 -## 特点 +请注意,Open-IM-Server 不作为独立产品运行,也不提供内置的帐户注册或登录服务。为了简化您的实施过程,我们已开源了 [chat repository](https://github.com/OpenIMSDK/chat),其中包括这些功能。与 Open-IM-Server 一起部署此聊天业务服务器可加快全面的聊天产品的设置。👥 -+ 开源 -+ 易于集成 -+ 良好的可扩展性 -+ 高性能 -+ 轻量级 -+ 支持多种协议 +为了进一步增强您的体验,我们还提供了 SDK 客户端,在其中实现了大多数复杂逻辑。可以在 [此链接](https://github.com/OpenIMSDK/openim-sdk-core) 找到 [SDK repository](https://github.com/OpenIMSDK/openim-sdk-core)。[chat repository](https://github.com/OpenIMSDK/chat) 是我们的业务服务器,而 'core' 代表 SDK 的高级封装,它们协同工作以提供卓越的结果。✨ -## 社区 +## :star2: 为什么选择 OpenIM -+ 访问中文官方网站:[OpenIM中文开发文档](https://doc.rentsoft.cn/) +**🔍 功能截图显示** -## 快速开始 +
-### 使用 docker-compose 部署 +| 💻🔄📱 多终端同步 🔄🖥️ | 📅⚡ 高效会议 🚀💼 | +| :----------------------------------------------------------: | :----------------------------------------------------------: | +| ![multiple-message](./assets/demo/multi-terminal-synchronization.png) | ![efficient-meetings](./assets/demo/efficient-meetings.png) | +| 📲🔄 **一对一和群聊** 👥🗣️ | 🎁💻 **特殊功能 - 自定义消息** ✉️🎨 | +| ![group-chat](./assets/demo/group-chat.png) | ![special-function](./assets/demo/special-function.png) | + +
+ +1. **全面的消息类型支持 :speech_balloon:** + + ✅ 支持几乎所有类型的消息,包括文本、图片、表情符号、语音、视频、地理位置、文件、报价、名片、系统通知、自定义消息等 + + ✅ 支持一对一和多人音视频通话 + + ✅ 为 iOS、Android、Flutter、uni-app、ReactNative、Electron、Web、H5 等多个平台提供终端支持 + +2. **随时随地的高效会议 :earth_americas:** + + ✅ 基于具有 100% 可靠强制信令功能的 IM (Instant Messaging),为与聊天应用程序深度集成的 IM 系统铺平了道路 + + ✅ 支持单次会议中的数百人,订阅人数达到数千,以及服务器端音视频录制 + +3. **适用于各种社交场景的一对一和群聊 :busts_in_silhouette:** + + ✅ OpenIM 有四种角色:应用程序管理员、群主、群管理员和普通成员 + + ✅ 强大的群特性,如静音、群公告、群验证、无限群成员和根据需要加载群消息 + +4. **独特的功能 :star2:** + + ✅ 支持读取并烧毁私人聊天,可自定义时长 + + ✅ 消息编辑功能扩大了社交场景,使即时通讯变得更加多样化和有趣 + +5. **开源 :open_hands:** + + ✅ OpenIM 的代码是开源的,数据自控,旨在构建一个全球领先的 IM 开源社区,包括客户端 SDK 和服务器 + + ✅ 基于开源服务器,已经开发了许多出色的开源项目,例如 [OpenKF](https://github.com/OpenIMSDK/OpenKF) (开源 AI 客户服务系统) + +6. **易于扩展 :wrench:** + + ✅ OpenIM 服务器是用 Golang 实现的,引入了创新的 "一切都是消息" 通信模型,简化了自定义消息和扩展功能的实现 + +7. **高性能 :racing_car:** + + ✅ OpenIM 支持集群中的分层治理架构,经过大量用户的测试,并抽象了在线消息、离线消息和历史消息的存储模型 + +8. **全平台支持 :tv:** + + ✅ 支持原生 iOS、Android;跨平台 Flutter、uni-app、ReactNative;主要的 Web 前端框架如 React、Vue;小程序和 Electron 支持的 PC 平台 + +9. **终极部署体验 🤖** + + ✅ 支持 [集群部署](https://github.com/OpenIMSDK/Open-IM-Server/edit/main/deployments/README.md) + + ✅ 支持多架构镜像,我们的 Docker 镜像不仅托管在 GitHub 上,而且还在阿里云和 Docker Hub 上支持多个架构。请访问 [我们的 GitHub packages](https://github.com/orgs/OpenIMSDK/packages?repo_name=Open-IM-Server) 并阅读我们的 [版本管理文档](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md) 以获取更多信息。 + +10. **开源社区的大生态系统 🤲** + + ✅ 我们有数万用户和许多解决方案来解决问题。 + + ✅ 我们有一个大型的开源社区叫 [OpenIMSDK](https://github.com/OpenIMSDK),它运行核心模块,我们还有一个开源社区叫 [openim-sigs](https://github.com/openim-sigs) 以探索更多基于 IM 的基础设施产品。 + +## :rocket: 快速开始 + +
使用 Docker Compose 部署 1. 克隆项目 ``` -git clone https://github.com/OpenIMSDK/Open-IM-Server -cd Open-IM-Server -git checkout release-v3.0 #or other release branch +bashCopy code# 选择您需要的 +BRANCH=release-v3.1 +git clone -b $BRANCH https://github.com/OpenIMSDK/Open-IM-Server openim && export openim=$(pwd)/openim && cd $openim && make build ``` -2. 修改 .env +> **注意** 阅读我们的发布策略:https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md + +1. 修改 `.env` ``` -此处主要修改相关组件密码 -USER=root #不用修改 -PASSWORD=openIM123 #8位以上的数字和字母组合密码,密码对redis mysql mongo生效,以及config/config.yaml中的accessSecret -ENDPOINT=http://127.0.0.1:10005 #minio对外服务的ip和端口,或用域名storage.xx.xx,app要能访问到此ip和端口或域名, -API_URL=http://127.0.0.1:10002/object/ #app要能访问到此ip和端口或域名, +bashCopy codeUSER=root #无需修改 +PASSWORD=openIM123 #8位或更多数字和字母的组合,此密码适用于redis、mysql、mongo,以及config/config.yaml中的accessSecret +ENDPOINT=http://127.0.0.1:10005 #minio的外部服务IP和端口,或使用域名storage.xx.xx,应用程序必须能够访问此IP和端口或域名, +API_URL=http://127.0.0.1:10002/object/ #应用程序必须能够访问此IP和端口或域名, DATA_DIR=./ #指定大磁盘目录 ``` -3. 部署和启动 +1. 部署并启动 -注意:此命令只能执行一次,它会根据.env 中的 PASSWORD 变量修改 docker-compose 中组件密码,并修改 config/config.yaml 中的组件密码 -如果.env 中的密码变了,需要先 docker-compose down ; rm components -rf 后再执行此命令。 +> **注意** 此命令只能执行一次。它会基于 `.env` 中的 `PASSWORD` 变量修改 docker-compose 中的组件密码,并修改 `config/config.yaml` 中的组件密码。如果 `.env` 中的密码发生变化,您需要首先执行 `docker-compose down`;`rm components -rf` 然后执行此命令。 ``` -chmod +x install_im_server.sh; -./install_im_server.sh; +bashCopy code +make install ``` -4. 检查服务 +1. 检查服务 ``` -cd scripts; -./docker_check_service.sh +bashCopy code +make check ``` ![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png) -### 使用源码编译 +
从源码编译 -1. Go 1.18或更高版本。 +您需要 `Go 1.18` 或更高版本,以及 `make`。 -2. 克隆 +版本详情:https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md - ``` - git clone https://github.com/OpenIMSDK/Open-IM-Server - cd Open-IM-Server - git checkout release-v3.0 #or other release branch - ``` +``` +bashCopy code# 选择您需要的 +BRANCH=release-v3.1 +git clone -b $BRANCH https://github.com/OpenIMSDK/Open-IM-Server openim && export openim=$(pwd)/openim && cd $openim && make build +``` -3. 编译 +阅读关于 [OpenIM 版本策略](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md) - ``` - cd Open-IM-server/scripts - chmod +x *.sh - ./build_all_service.sh - ``` +使用 `make help` 来查看 OpenIM 支持的指令。 -所有服务已成功构建如图所示 +如图所示,所有服务已成功构建 -![编译成功](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/build.png) +![成功编译](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/build.png) -### 组件配置说明 +
组件配置说明 -config/config.yaml中针对存储组件有详细的配置说明 +config/config.yaml 文件为存储组件提供了详细的配置说明。 + +- Zookeeper + + - 用于 RPC 服务发现和注册,支持集群。 -+ Zookeeper - + 用于RPC 服务发现和注册,支持集群。 - - ```` ``` - zookeeper: + bashCopy codezookeeper: schema: openim #不建议修改 address: [ 127.0.0.1:2181 ] #地址 username: #用户名 password: #密码 ``` - ```` - - - -+ MySQL - - + 用于存储用户、关系链、群组,支持数据库主备。 - + +- MySQL + + - 用于存储用户、关系和群组,支持主从数据库。 + ``` - mysql: + bashCopy codemysql: address: [ 127.0.0.1:13306 ] #地址 username: root #用户名 password: openIM123 #密码 database: openIM_v2 #不建议修改 - maxOpenConn: 1000 #最大连接数 - maxIdleConn: 100 #最大空闲连接数 - maxLifeTime: 60 #连接可以重复使用的最长时间(秒) - logLevel: 4 #日志级别 1=slient 2=error 3=warn 4=info - slowThreshold: 500 #慢语句阈值 (毫秒) + maxOpenConn: 1000 #最大连接 + maxIdleConn: 100 #最大空闲连接 + maxLifeTime: 60 #连接可重用的最大时间(秒) + logLevel: 4 #日志级别 1=静音 2=错误 3=警告 4=信息 + slowThreshold: 500 #慢语句阈值(毫秒) ``` - - - -+ Mongo - + 用于存储离线消息,支持mongo分片集群。 - + +- Mongo + + - 用于存储离线消息,支持 mongo 分片集群。 + ``` - mongo: - uri: #不为空则直接使用该值 + bashCopy codemongo: + uri: #如果不为空,则直接使用此值 address: [ 127.0.0.1:37017 ] #地址 - database: openIM #mongo db 默认即可 + database: openIM #默认 mongo 数据库 username: root #用户名 password: openIM123 #密码 maxPoolSize: 100 #最大连接数 ``` - -+ Redis - + 用于存储消息序列号、最新消息、用户token及mysql缓存,支持集群部署。 - + +- Redis + + - 用于存储消息序列号、最新消息、用户令牌和 mysql 缓存,支持集群部署。 + ``` - redis: + bashCopy coderedis: address: [ 127.0.0.1:16379 ] #地址 username: #用户名 password: openIM123 #密码 ``` - -+ Kafka - + 用于消息队列,用于消息解耦,支持集群部署。 - + +- Kafka + + - 用于消息队列,用于消息解耦,支持集群部署。 + ``` - kafka: + bashCopy codekafka: username: #用户名 password: #密码 addr: [ 127.0.0.1:9092 ] #地址 @@ -195,71 +254,104 @@ config/config.yaml中针对存储组件有详细的配置说明 msgToModify: modify ``` -### 启停服务 +
启动和停止服务 启动服务 ``` -./start_all.sh; +bashCopy code +./scripts/start-all.sh; ``` 检查服务 ``` -./check_all.sh +bashCopy code +./scripts/check-all.sh ``` 停止服务 ``` -./stop_all.sh +bashCopy code +./scripts/stop-all.sh ``` -### 开放 IM 端口 +
-| TCP 端口 | 说明 | 操作 | -| --------- | ----------------------------------------------------- | --------------------------------------- | -| TCP:10001 | ws 协议,消息端口,如消息发送、推送等,用于客户端 SDK | 端口放行或 nginx 反向代理,并关闭防火墙 | -| TCP:10002 | api 端口,如用户、好友、群组、消息等接口。 | 端口放行或 nginx 反向代理,并关闭防火墙 | -| TCP:10005 | 选择 minio 存储时需要(openIM 默认使用 minio 存储) | 端口放行或 nginx 反向代理,并关闭防火墙 | +
开放 IM 端口 -### 开放 Chat 端口 +| TCP 端口 | 描述 | 操作 | +| --------- | --------------------------------------------------- | --------------------------------------- | +| TCP:10001 | ws 协议,消息端口如消息发送、推送等,用于客户端 SDK | 端口释放或 nginx 反向代理,并关闭防火墙 | +| TCP:10002 | api 端口,如用户、朋友、组、消息接口。 | 端口释放或 nginx 反向代理,并关闭防火墙 | +| TCP:10005 | 选择 minio 存储时所需 (openIM 默认使用 minio 存储) | 端口释放或 nginx 反向代理,并关闭防火墙 | -| TCP 端口 | 说明 | 操作 | +
开放聊天端口 + +- 聊天仓库: https://github.com/OpenIMSDK/chat + +| TCP 端口 | 描述 | 操作 | | --------- | ------------------------ | --------------------------------------- | -| TCP:10008 | 业务系统,如注册、登录等 | 端口放行或 nginx 反向代理,并关闭防火墙 | -| TCP:10009 | 管理后台,如统计、封号等 | 端口放行或 nginx 反向代理,并关闭防火墙 | +| TCP:10008 | 业务系统,如注册、登录等 | 端口释放或 nginx 反向代理,并关闭防火墙 | +| TCP:10009 | 管理后台,如统计、封禁等 | 端口释放或 nginx 反向代理,并关闭防火墙 | -## APP和OpenIM关系 +
-OpenIM 是开源的即时通讯组件,它并不是一个独立的产品,此图展示了AppServer、AppClient、Open-IM-Server以及Open-IM-SDK之间的关系 +## :link: APP 和 OpenIM 之间的关系 -![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/open-im-server.png](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/open-im-server.png) +OpenIM 不仅仅是一个开源的即时消息组件,它是您的应用程序生态系统的一个不可分割的部分。查看此图表以了解 AppServer、AppClient、Open-IM-Server 和 Open-IM-SDK 如何互动。 -## 整体架构 +![App-OpenIM 关系](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/open-im-server.png) -![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/Architecture.jpg](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/Architecture.jpg) +## :building_construction: 总体架构 -## 开始开发 OpenIM +深入了解 Open-IM-Server 的功能与我们的架构图。 -[社区存储库](https://github.com/OpenIMSDK/community)包含有关从源代码构建 Kubernetes、如何贡献代码和文档。 +![总体架构](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/Architecture.jpg) -## 贡献 +## :hammer_and_wrench: 开始开发 OpenIM -欢迎对该项目进行贡献!请参见 [CONTRIBUTING.md](http://CONTRIBUTING.md) 了解详细信息。 +OpenIM 我们的目标是建立一个顶级的开源社区。我们有一套标准,在 [Community repository](https://github.com/OpenIMSDK/community) 中。 -## 社区会议 +如果您想为这个 Open-IM-Server 仓库做贡献,请阅读我们的 [贡献者文档](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/CONTRIBUTING.md)。 -我们希望任何人都能参与我们的社区,我们提供礼品和奖励,并欢迎您每周四晚上加入我们。 +在您开始之前,请确保您的更改是需要的。最好的方法是创建一个 [新的讨论](https://github.com/OpenIMSDK/Open-IM-Server/discussions/new/choose) 或 [Slack 通讯](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg),或者如果您发现一个问题,首先 [报告它](https://github.com/OpenIMSDK/Open-IM-Server/issues/new/choose)。 -我们在 [GitHub 讨论](https://github.com/OpenIMSDK/Open-IM-Server/discussions/categories/meeting) 中记录每个 [两周会议](https://github.com/OpenIMSDK/Open-IM-Server/issues/381),我们的记录写在 [Google 文档](https://docs.google.com/document/d/1nx8MDpuG74NASx081JcCpxPgDITNTpIIos0DS6Vr9GU/edit?usp=sharing) 中。 +- [代码标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/go_code.md) +- [Docker 图像标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md) +- [目录标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/directory.md) +- [提交标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/commit.md) +- [版本控制标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md) +- [接口标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/api.md) +- [日志标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/log.md) +- [错误代码标准](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/error_code.md) -## 谁在使用 Open-IM-Server +## :busts_in_silhouette: 社区 -[用户案例研究](https://github.com/OpenIMSDK/community/blob/main/ADOPTERS.md) 页面包括该项目的用户列表。您可以留下 [📝评论](https://github.com/OpenIMSDK/Open-IM-Server/issues/379) 让我们知道您的用例。 +- 📚 [OpenIM 社区](https://github.com/OpenIMSDK/community) +- 💕 [OpenIM 兴趣小组](https://github.com/Openim-sigs) +- 🚀 [加入我们的 Slack 社区](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) +- :eyes: [加入我们的微信群 (微信群)](https://openim-1253691595.cos.ap-nanjing.myqcloud.com/WechatIMG20.jpeg) -![https://github.com/OpenIMSDK/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg](https://github.com/OpenIMSDK/OpenIM-Docs/blob/main/docs/images/WechatIMG20.jpeg) +## :calendar: 社区会议 -## 许可证 +我们希望任何人都可以参与我们的社区并贡献代码,我们提供礼物和奖励,欢迎您每周四晚上加入我们。 -Open-IM-Server 使用 Apache 2.0 许可证。有关详情,请参阅 LICENSE 文件。 +我们的会议在 [OpenIM Slack](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) 🎯,然后您可以搜索 Open-IM-Server 管道加入。 + +我们在 [GitHub 讨论](https://github.com/OpenIMSDK/Open-IM-Server/discussions/categories/meeting) 中记下每次 [双周会议](https://github.com/orgs/OpenIMSDK/discussions/categories/meeting) 的笔记,我们的历史会议记录以及会议回放都可在 [Google Docs :bookmark_tabs:](https://docs.google.com/document/d/1nx8MDpuG74NASx081JcCpxPgDITNTpIIos0DS6Vr9GU/edit?usp=sharing) 中找到。 + +## :eyes: 谁在使用 OpenIM + +查看我们的 [用户案例研究](https://github.com/OpenIMSDK/community/blob/main/ADOPTERS.md) 页面以获取项目用户列表。不要犹豫,留下一个 [📝评论](https://github.com/OpenIMSDK/Open-IM-Server/issues/379) 并分享您的使用案例。 + +## :page_facing_up: 许可证 + +OpenIM 根据 Apache 2.0 许可证授权。请查看 [LICENSE](https://github.com/OpenIMSDK/Open-IM-Server/tree/main/LICENSE) 以获取完整的许可证文本。 + +OpenIM logo,包括其变体和动画版本,在此存储库 [OpenIM](https://github.com/OpenIMSDK/Open-IM-Server) 下的 [assets/logo](./assets/logo) 和 [assets/logo-gif](./assets/logo-gif) 目录中显示,受版权法保护。 + +## 🔮 感谢我们的贡献者! + + \ No newline at end of file diff --git a/README.md b/README.md index ecb39213b..5a71bd527 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ ## ✨ About OpenIM -Open-IM-Server, crafted meticulously using pure Golang, stands as a robust instant messaging server. Its unique approach to communication, via JSON over WebSocket, treats every interaction as a message. This simplifies customization and eliminates the need for tinkering with server code. Harnessing the power of microservice architecture, the server can be deployed via clusters, promising impressive performance and scalability. +Open-IM-Server, meticulously developed in pure Golang, is a powerful instant messaging server. Its distinct communication method, employing pb+websocket, views every interaction as a message, streamlining customization without altering server code. Built on a microservice architecture, it offers deployment through clusters for outstanding performance and scalability. Open-IM-Server is more than an instant messaging server; it's a powerful tool for incorporating real-time networking into your applications, positioning itself as your premier choice for integration! 🚀 @@ -111,73 +111,113 @@ Further enhancing your experience, we also provide an SDK client, wherein most c ## :rocket: Quick Start +You can quickly learn OpenIM engineering solutions, all it takes is one simple command: + +```bash +$ make demo +``` + +🤲 In order to facilitate the user experience, we have provided a variety of deployment solutions, you can choose your own deployment method according to the list below: +
Deploying with Docker Compose -1. Clone the project + +> docker compose will not be maintained in future versions, but it is still the easiest and most convenient way to organize docker compose deployments into a separate project https://github.com/openim-sigs/openim-docker to maintain. + +**1. Clone the project** + ```bash -# choose what you need -BRANCH=release-v3.1 -git clone -b $BRANCH https://github.com/OpenIMSDK/Open-IM-Server openim && export openim=$(pwd)/openim && cd $openim && make build +# choose what you need, We take branch 3.2 as an example +$ BRANCH=release-v3.2 +$ git clone -b $BRANCH https://github.com/OpenIMSDK/Open-IM-Server openim/openim-server && export openim_dir=$(pwd)/openim && cd ${openim_dir}/openim-server ``` > **Note** -> Read our release policy: https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md +> If you don't know OpenIM's versioning policy, 📚Read our release policy: https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md -2. Modify `.env` + + +**2. Configure the config file** + +If you tried to get started quickly with `make demo`, then you know that our config file is generated by automation. + +You can use `make init` to quickly initialize a configuration file ```bash -USER=root #no need to modify -PASSWORD=openIM123 #A combination of 8 or more numbers and letters, this password applies to redis, mysql, mongo, as well as accessSecret in config/config.yaml -ENDPOINT=http://127.0.0.1:10005 #minio's external service IP and port, or use the domain name storage.xx.xx, the app must be able to access this IP and port or domain, -API_URL=http://127.0.0.1:10002/object/ #the app must be able to access this IP and port or domain, -DATA_DIR=./ #designate large disk directory +$ make init +$ git diff ``` -3. Deploy and start +Then feel free to modify your current config file, you can also modify `/scripts/install/environment.sh` document template, `make init` is essentially rendering `environment.sh` template, and then through the `make init` to automatically generate a new configuration. -> **Note** -> This command can only be executed once. It will modify the component passwords in docker-compose based on the `PASSWORD` variable in `.env`, and modify the component passwords in `config/config.yaml`. If the password in `.env` changes, you need to first execute `docker-compose down`; `rm components -rf` and then execute this command. +If you only need to change the config file for a short time, or if you don't want to make any major changes in the future, you can modify the `.env file directly ```bash -make install +USER=root #no need to modify +PASSWORD=openIM123 #A combination of 8 or more numbers and letters, this password applies to redis, mysql, mongo, as well as accessSecret in config/config.yaml +ENDPOINT=http://127.0.0.1:10005 #minio's external service IP and port, or use the domain name storage.xx.xx, the app must be able to access this IP and port or domain, +API_URL=http://127.0.0.1:10002/object/ #the app must be able to access this IP and port or domain, +DATA_DIR=./ #designate large disk directory +``` + +**3. Deploy and start** + +> **Note** +> +> You can deploy either directly with `make install` or with `docker compose up`, the logic is the same + +```bash +$ make install +# OR +$ docker-compose up ``` 4. Check the service ```bash -make check +$ make check ``` -![https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/docker_build.png) +Looking at the command line at this point, there are two items in the output, checking for the start of the component port that OpenIM depends on, and the start of the OpenIM core component
Compile from Source + Ur need `Go 1.18` or higher version, and `make`. + +```bash +go version && make --version || echo "Error: One of the commands failed." +``` + Version Details: https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md ```bash # choose what you need -BRANCH=release-v3.1 -git clone -b $BRANCH https://github.com/OpenIMSDK/Open-IM-Server openim && export openim=$(pwd)/openim && cd $openim && make build +$ BRANCH=release-v3.1 +$ git clone -b $BRANCH https://github.com/OpenIMSDK/Open-IM-Server openim && export openim=$(pwd)/openim && cd $openim && make start ``` -Read about the [OpenIM Version Policy](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md) +> `make help` to help you see the instructions supported by OpenIM. -`make help` to help you see the instructions supported by OpenIM. +Use `make check` to check all component starts -All services have been successfully built as shown in the figure +```bash +$ make check +``` -![Successful Compilation](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/images/build.png) +You can use the `make help-all` see OpenIM in action.
Component Configuration Instructions +The `config/config.yaml` file has detailed configuration instructions for the storage components. -The config/config.yaml file has detailed configuration instructions for the storage components. + +The config file is available via [environment.sh](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/scripts/install/environment.sh) configuration [openim.yaml](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/deployments/templates/openim.yaml) template, and then through the `make init` to automatically generate a new configuration. - Zookeeper @@ -260,30 +300,16 @@ The config/config.yaml file has detailed configuration instructions for the stor
-
Start and Stop Services +
Deployed with kubernetes -Start services -``` -./scripts/start_all.sh; -``` - -Check services - -``` -./scripts/check_all.sh -``` - -Stop services - -``` -./scripts/stop_all.sh -``` +read: https://github.com/OpenIMSDK/Open-IM-Server/blob/main/deployments/README.md
Open IM Ports + | TCP Port | Description | Operation | | --------- | ------------------------------------------------------------ | ----------------------------------------------------- | | TCP:10001 | ws protocol, message port such as message sending, pushing etc, used for client SDK | Port release or nginx reverse proxy, and firewall off | @@ -294,6 +320,7 @@ Stop services
Open Chat Ports + + chat warehouse: https://github.com/OpenIMSDK/chat | TCP Port | Description | Operation | @@ -303,6 +330,7 @@ Stop services
+ ## :link: Relationship Between APP and OpenIM OpenIM isn't just an open-source instant messaging component, it's an integral part of your application ecosystem. Check out this diagram to understand how AppServer, AppClient, Open-IM-Server, and Open-IM-SDK interact. diff --git a/assets/demo/hello-openim.png b/assets/demo/hello-openim.png new file mode 100644 index 0000000000000000000000000000000000000000..2dd7e48ee5f3de5f1404cb5752b9d337c6bd2510 GIT binary patch literal 49844 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 B)~Wyi literal 0 HcmV?d00001 diff --git a/.goreleaser.yaml b/build/goreleaser.yaml similarity index 78% rename from .goreleaser.yaml rename to build/goreleaser.yaml index 184949283..906f49d78 100644 --- a/.goreleaser.yaml +++ b/build/goreleaser.yaml @@ -479,53 +479,4 @@ checksum: algorithm: sha256 release: - - prerelease: auto - - footer: | - - ## Welcome to the {{ .Tag }} release of [chat](https://github.com/OpenIMSDK/chat)!🎉🎉! - - **Full Changelog**: https://github.com/OpenIMSDK/Open-IM-Server/compare/{{ .PreviousTag }}...{{ .Tag }} - - ## Helping out - - + We release logs are recorded on [✨CHANGELOG](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/CHANGELOG/CHANGELOG.md) - - + For information on versions of OpenIM and how to maintain branches, read [📚this article](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/version.md) - - + If you wish to use mirroring, read OpenIM's [image management policy](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md) - - **Want to be one of them 😘?** - -

- - - - - - - - - -

- - > **Note** - > @openimbot and @kubbot have made great contributions to the community as community 🤖robots(@openimsdk/bot), respectively. - > Thanks to the @openimsdk/openim team for all their hard work on this release. - > Thank you to all the [💕developers and contributors](https://github.com/OpenIMSDK/Open-IM-Server/graphs/contributors), people from all over the world, OpenIM brings us together - > Contributions to this project are welcome! Please see [CONTRIBUTING.md](https://github.com/OpenIMSDK/Open-IM-Server/blob/main/CONTRIBUTING.md) for details. - - ## Get Involved with OpenIM! - - **Here are some ways to get involved with the OpenIM community:** - - 📢 **Slack Channel**: Join our Slack channels for discussions, communication, and support. Click [here](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) to join the Open-IM-Server Slack team channel. - - 📧 **Gmail Contact**: If you have any questions, suggestions, or feedback for our open-source projects, please feel free to [contact us via email](https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=winxu81@gmail.com). - - 📖 **Blog**: Stay up-to-date with OpenIM-Server projects and trends by reading our [blog](https://doc.rentsoft.cn/). We share the latest developments, tech trends, and other interesting information related to OpenIM. - - 📱 **WeChat**: Add us on WeChat (QR Code) and indicate that you are a user or developer of Open-IM-Server. We'll process your request as soon as possible. - - Remember, your contributions play a vital role in making OpenIM successful, and we look forward to your active participation in our community! 🙌 \ No newline at end of file + prerelease: auto \ No newline at end of file diff --git a/build/docker/openim-api/Dockerfile b/build/images/openim-api/Dockerfile similarity index 85% rename from build/docker/openim-api/Dockerfile rename to build/images/openim-api/Dockerfile index 7b2a4bd8e..0d738e5bb 100644 --- a/build/docker/openim-api/Dockerfile +++ b/build/images/openim-api/Dockerfile @@ -34,6 +34,7 @@ COPY . . RUN make clean RUN make build BINS=openim-api +# FROM ghcr.io/openim-sigs/openim-bash-image:latest FROM ghcr.io/openim-sigs/openim-bash-image:latest WORKDIR /openim/openim-server @@ -41,6 +42,8 @@ WORKDIR /openim/openim-server COPY --from=builder /openim/openim-server/_output/bin/platforms /openim/openim-server/_output/bin/platforms COPY --from=builder /openim/openim-server/config /openim/openim-server/config -EXPOSE ${10002} +ENV PORT 10002 -CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-api --port 10002 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file +EXPOSE ${PORT} + +CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-api --port ${PORT} -c ${SERVER_WORKDIR}/config"] \ No newline at end of file diff --git a/build/docker/openim-cmdutils/Dockerfile b/build/images/openim-cmdutils/Dockerfile similarity index 86% rename from build/docker/openim-cmdutils/Dockerfile rename to build/images/openim-cmdutils/Dockerfile index eab064dc3..47c4cf7be 100644 --- a/build/docker/openim-cmdutils/Dockerfile +++ b/build/images/openim-cmdutils/Dockerfile @@ -39,7 +39,7 @@ FROM ghcr.io/openim-sigs/openim-bash-image:latest WORKDIR /openim/openim-server -COPY --from=builder ${SERVER_WORKDIR}/_output/bin/platforms /openim/openim-server/_output/bin/platforms +COPY --from=builder $OPENIM_SERVER_BINDIR/platforms /openim/openim-server/_output/bin/platforms COPY --from=builder ${SERVER_WORKDIR}/config /openim/openim-server/config -CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-cmdutils"] +CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-cmdutils"] diff --git a/build/docker/openim-crontask/Dockerfile b/build/images/openim-crontask/Dockerfile similarity index 93% rename from build/docker/openim-crontask/Dockerfile rename to build/images/openim-crontask/Dockerfile index 00c9a5244..b517c48ea 100644 --- a/build/docker/openim-crontask/Dockerfile +++ b/build/images/openim-crontask/Dockerfile @@ -41,4 +41,4 @@ WORKDIR /openim/openim-server COPY --from=builder /openim/openim-server/_output/bin/platforms /openim/openim-server/_output/bin/platforms COPY --from=builder /openim/openim-server/config /openim/openim-server/config -CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-crontask"] +CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-crontask"] diff --git a/build/docker/openim-msggateway/Dockerfile b/build/images/openim-msggateway/Dockerfile similarity index 92% rename from build/docker/openim-msggateway/Dockerfile rename to build/images/openim-msggateway/Dockerfile index 1c353b9e5..de6762114 100644 --- a/build/docker/openim-msggateway/Dockerfile +++ b/build/images/openim-msggateway/Dockerfile @@ -47,4 +47,4 @@ ENV ARCH ${ARCH} EXPOSE 10140 EXPOSE 10001 -CMD ${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-msggateway --port 10140 --ws_port 10001 \ No newline at end of file +CMD ${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-msggateway --port 10140 --ws_port 10001 \ No newline at end of file diff --git a/build/docker/openim-msgtransfer/Dockerfile b/build/images/openim-msgtransfer/Dockerfile similarity index 94% rename from build/docker/openim-msgtransfer/Dockerfile rename to build/images/openim-msgtransfer/Dockerfile index 0db1377c1..1f22b5c95 100644 --- a/build/docker/openim-msgtransfer/Dockerfile +++ b/build/images/openim-msgtransfer/Dockerfile @@ -44,4 +44,4 @@ WORKDIR /openim/openim-server COPY --from=builder /openim/openim-server/_output/bin/platforms /openim/openim-server/_output/bin/platforms COPY --from=builder /openim/openim-server/config /openim/openim-server/config -CMD ${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-msgtransfer \ No newline at end of file +CMD ${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-msgtransfer \ No newline at end of file diff --git a/build/docker/openim-push/Dockerfile b/build/images/openim-push/Dockerfile similarity index 93% rename from build/docker/openim-push/Dockerfile rename to build/images/openim-push/Dockerfile index c1824b185..a5072bbb4 100644 --- a/build/docker/openim-push/Dockerfile +++ b/build/images/openim-push/Dockerfile @@ -46,4 +46,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config EXPOSE 10170 -CMD ${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-push --port 10170 \ No newline at end of file +CMD ${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-push --port 10170 \ No newline at end of file diff --git a/build/docker/openim-rpc-auth/Dockerfile b/build/images/openim-rpc-auth/Dockerfile similarity index 91% rename from build/docker/openim-rpc-auth/Dockerfile rename to build/images/openim-rpc-auth/Dockerfile index 87c30e559..427483db3 100644 --- a/build/docker/openim-rpc-auth/Dockerfile +++ b/build/images/openim-rpc-auth/Dockerfile @@ -49,4 +49,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config EXPOSE 10160 -CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-auth --port 10160 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file +CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-auth --port 10160 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file diff --git a/build/docker/openim-rpc-conversation/Dockerfile b/build/images/openim-rpc-conversation/Dockerfile similarity index 92% rename from build/docker/openim-rpc-conversation/Dockerfile rename to build/images/openim-rpc-conversation/Dockerfile index 2e6b76996..1764a69df 100644 --- a/build/docker/openim-rpc-conversation/Dockerfile +++ b/build/images/openim-rpc-conversation/Dockerfile @@ -56,4 +56,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config EXPOSE 10230 EXPOSE 20230 -CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-conversation --port 10230 --prometheus_port 20230 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file +CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-conversation --port 10230 --prometheus_port 20230 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file diff --git a/build/docker/openim-rpc-friend/Dockerfile b/build/images/openim-rpc-friend/Dockerfile similarity index 92% rename from build/docker/openim-rpc-friend/Dockerfile rename to build/images/openim-rpc-friend/Dockerfile index 47e44b104..efc34c4e5 100644 --- a/build/docker/openim-rpc-friend/Dockerfile +++ b/build/images/openim-rpc-friend/Dockerfile @@ -56,4 +56,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config EXPOSE 10120 EXPOSE 20120 -CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-friend --port 10120 --prometheus_port 20120 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file +CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-friend --port 10120 --prometheus_port 20120 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file diff --git a/build/docker/openim-rpc-group/Dockerfile b/build/images/openim-rpc-group/Dockerfile similarity index 92% rename from build/docker/openim-rpc-group/Dockerfile rename to build/images/openim-rpc-group/Dockerfile index 70facaae2..55a3a800c 100644 --- a/build/docker/openim-rpc-group/Dockerfile +++ b/build/images/openim-rpc-group/Dockerfile @@ -56,4 +56,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config EXPOSE 10150 EXPOSE 20150 -CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-group --port 10150 --prometheus_port 20150 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file +CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-group --port 10150 --prometheus_port 20150 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file diff --git a/build/docker/openim-rpc-msg/Dockerfile b/build/images/openim-rpc-msg/Dockerfile similarity index 92% rename from build/docker/openim-rpc-msg/Dockerfile rename to build/images/openim-rpc-msg/Dockerfile index 664d0cdce..0058450e6 100644 --- a/build/docker/openim-rpc-msg/Dockerfile +++ b/build/images/openim-rpc-msg/Dockerfile @@ -56,4 +56,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config EXPOSE 10130 EXPOSE 20130 -CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-msg --port 10130 --prometheus_port 20130 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file +CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-msg --port 10130 --prometheus_port 20130 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file diff --git a/build/docker/openim-rpc-third/Dockerfile b/build/images/openim-rpc-third/Dockerfile similarity index 93% rename from build/docker/openim-rpc-third/Dockerfile rename to build/images/openim-rpc-third/Dockerfile index 20e9102eb..f1d5fcc8c 100644 --- a/build/docker/openim-rpc-third/Dockerfile +++ b/build/images/openim-rpc-third/Dockerfile @@ -55,4 +55,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config EXPOSE 10200 -CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-third --port 10200 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file +CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-third --port 10200 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file diff --git a/build/docker/openim-rpc-user/Dockerfile b/build/images/openim-rpc-user/Dockerfile similarity index 93% rename from build/docker/openim-rpc-user/Dockerfile rename to build/images/openim-rpc-user/Dockerfile index 86e53b1b6..338bf1305 100644 --- a/build/docker/openim-rpc-user/Dockerfile +++ b/build/images/openim-rpc-user/Dockerfile @@ -55,4 +55,4 @@ COPY --from=builder /openim/openim-server/config /openim/openim-server/config EXPOSE 10110 -CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/${OS}/${ARCH}/openim-rpc-user --port 10110 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file +CMD ["bash", "-c","${OPENIM_SERVER_BINDIR}/platforms/$(get_os)/$(get_arch)/openim-rpc-user --port 10110 -c ${SERVER_WORKDIR}/config"] \ No newline at end of file diff --git a/config/config-copy.yaml b/config/config-copy.yaml new file mode 100644 index 000000000..27f01fb8b --- /dev/null +++ b/config/config-copy.yaml @@ -0,0 +1,378 @@ +# 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. + +# ----------------------------------------------------------------- +# Infrastructural configurations, please modify based on your setup +# ----------------------------------------------------------------- + +###################### Zookeeper ###################### +# Zookeeper configuration +# It's not recommended to modify the schema +# +# Zookeeper address +# Zookeeper username +# Zookeeper password +zookeeper: + schema: openim + address: [ 127.0.0.1:2181 ] + username: + password: + +###################### Mysql ###################### +# MySQL configuration +# Currently, only single machine setup is supported +# +# Maximum number of open connections +# Maximum number of idle connections +# Maximum lifetime in seconds a connection can be reused +# Log level: 1=slient, 2=error, 3=warn, 4=info +# Slow query threshold in milliseconds +mysql: + address: [ 127.0.0.1:13306 ] + username: root + password: openIM123 + database: openIM_v3 + maxOpenConn: 1000 + maxIdleConn: 100 + maxLifeTime: 60 + logLevel: 4 + slowThreshold: 500 + +###################### Mongo ###################### +# MongoDB configuration +# If uri is not empty, it will be used directly +# +# MongoDB address for standalone setup, Mongos address for sharded cluster setup +# Default MongoDB database name +# Maximum connection pool size +mongo: + uri: + address: [ 127.0.0.1:37017 ] + database: openIM_v3 + username: root + password: openIM123 + maxPoolSize: 100 + +###################### Redis ###################### +# Redis configuration +# +# Username is required only for Redis version 6.0+ +redis: + address: [ 127.0.0.1:16379 ] + username: + password: openIM123 + +###################### Kafka ###################### +# 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: [ 127.0.0.1:9092 ] + latestMsgToRedis: + topic: "latestMsgToRedis" + offlineMsgToMongo: + topic: "offlineMsgToMongoMysql" + msgToPush: + topic: "msgToPush" + consumerGroupID: + msgToRedis: redis + msgToMongo: mongo + msgToMySql: mysql + msgToPush: push + +###################### RPC ###################### +# 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 ###################### +# API configuration +# +# API service port +# Default listen IP is 0.0.0.0 +api: + openImApiPort: [ 10002 ] + listenIP: 0.0.0.0 + +###################### Gateway ###################### +# 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://127.0.0.1:10005" + accessKeyID: "root" + secretAccessKey: "openIM123" + sessionToken: "" + signEndpoint: "http://127.0.0.1:10005" + cos: + bucketURL: "https://temp-1252357374.cos.ap-chengdu.myqcloud.com" + secretID: "" + secretKey: "" + sessionToken: "" + oss: + endpoint: "https://oss-cn-chengdu.aliyuncs.com" + bucket: "demo-9999999" + bucketURL: "https://demo-9999999.oss-cn-chengdu.aliyuncs.com" + accessKeyID: "" + accessKeySecret: "" + sessionToken: "" + +# 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 ] + openImMessageGatewayPort: [ 10140 ] + openImGroupPort: [ 10150 ] + openImAuthPort: [ 10160 ] + openImPushPort: [ 10170 ] + openImConversationPort: [ 10180 ] + openImThirdPort: [ 10190 ] + +# 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 +# +# 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: ../../../../../logs/ + rotationTime: 24 + remainRotationCount: 2 + remainLogLevel: 6 + isStdout: false + isJson: false + withStack: false + +# 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 + 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 +manager: + userID: [ "openIM123456","openIM654321","openIMAdmin" ] + nickname: [ "system1","system2", "system3" ] + +# 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 + +# Callback configuration +# +# Callback URL +# Whether to enable this callback event +# Timeout in seconds +# Whether to continue execution if callback fails +callback: + url: + beforeSendSingleMsg: + enable: false + timeout: 5 + failedContinue: true + afterSendSingleMsg: + enable: false + timeout: 5 + beforeSendGroupMsg: + enable: false + timeout: 5 + failedContinue: true + afterSendGroupMsg: + enable: false + timeout: 5 + msgModify: + enable: false + timeout: 5 + failedContinue: true + userOnline: + enable: false + timeout: 5 + userOffline: + enable: false + timeout: 5 + userKickOff: + enable: false + timeout: 5 + 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 + beforeCreateGroup: + enable: false + timeout: 5 + failedContinue: true + beforeMemberJoinGroup: + enable: false + timeout: 5 + failedContinue: true + beforeSetGroupMemberInfo: + enable: false + timeout: 5 + failedContinue: true + setMessageReactionExtensions: + enable: false + timeout: 5 + failedContinue: true + +###################### Prometheus ###################### +# Prometheus configuration +# 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: false + 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 ] \ No newline at end of file diff --git a/config/config.yaml b/config/config.yaml index 035577b3d..27f01fb8b 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -375,4 +375,4 @@ prometheus: conversationPrometheusPort: [ 20230 ] rtcPrometheusPort: [ 21300 ] thirdPrometheusPort: [ 21301 ] - messageTransferPrometheusPort: [ 21400, 21401, 21402, 21403 ] + messageTransferPrometheusPort: [ 21400, 21401, 21402, 21403 ] \ No newline at end of file diff --git a/deployments/README.md b/deployments/README.md index 602371fb0..dd59f09cf 100644 --- a/deployments/README.md +++ b/deployments/README.md @@ -12,7 +12,6 @@ OpenIM 支持很多种集群化部署方式,包括但不限于 helm, sealos, k - https://github.com/showurl/deploy-openim - ### 依赖检查 ```bash diff --git a/openim-chat/scripts/function.sh b/deployments/templates/env_template.yaml similarity index 58% rename from openim-chat/scripts/function.sh rename to deployments/templates/env_template.yaml index 65209049a..687c04453 100644 --- a/openim-chat/scripts/function.sh +++ b/deployments/templates/env_template.yaml @@ -1,7 +1,4 @@ -#!/usr/bin/env bash - - -# Copyright © 2023 OpenIM open source community. All rights reserved. +# 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. @@ -15,18 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -#input:[10023,2323,3434] -#output:10023 2323 3434 -list_to_string(){ - ports_list=$* - sub_s1=`echo $ports_list | sed 's/ //g'` - sub_s2=${sub_s1//,/ } - sub_s3=${sub_s2#*[} - sub_s4=${sub_s3%]*} - ports_array=$sub_s4 -} - -remove_space(){ - value=$* - result=`echo $value | sed 's/ //g'` -} \ No newline at end of file +USER=${USER} +PASSWORD=${PASSWORD} +MINIO_ENDPOINT=${MINIO_ENDPOINT} +API_URL=${API_URL} +DATA_DIR=${DATA_DIR} \ No newline at end of file diff --git a/deployments/templates/init/README.md b/deployments/templates/init/README.md new file mode 100644 index 000000000..460739372 --- /dev/null +++ b/deployments/templates/init/README.md @@ -0,0 +1,220 @@ +# Systemd Configuration, Installation, and Startup + +- [Systemd Configuration, Installation, and Startup](#systemd-configuration-installation-and-startup) + - [1. Introduction](#1-introduction) + - [2. Prerequisites (Requires root permissions)](#2-prerequisites-requires-root-permissions) + - [3. Create `openim-api` systemd unit template file](#3-create-openim-api-systemd-unit-template-file) + - [4. Copy systemd unit template file to systemd config directory (Requires root permissions)](#4-copy-systemd-unit-template-file-to-systemd-config-directory-requires-root-permissions) + - [5. Start systemd service](#5-start-systemd-service) + +## 1. Introduction + +Systemd is the default service management form for the latest Linux distributions, replacing the original init. + +Format introduction: + +```bash +[Unit] : Unit of the service + +Description: Brief description of the service + +[Service]: Configuration of the service's runtime behavior + +ExecStart: Complete path of the program + +Restart: Restart configurations like no, always, on-success, on-failure, on-abnormal, on-abort, on-watchdog + +[Install]: Installation configuration + +WantedBy: Multi-user, etc. +``` + +For more details, refer to: [Systemd Service Manual](https://www.freedesktop.org/software/systemd/man/systemd.service.html) + +Starting command: + +```bash +systemctl daemon-reload && systemctl enable openim-api && systemctl restart openim-api +``` + +Service status: + +```bash +systemctl status openim-api +``` + +Stop command: + +```bash +systemctl stop openim-api +``` + +More command: +```bash +# 列出正在运行的Unit,可以直接使用systemctl +systemctl list-units + +# 列出所有Unit,包括没有找到配置文件的或者启动失败的 +systemctl list-units --all + +# 列出所有没有运行的 Unit +systemctl list-units --all --state=inactive + +# 列出所有加载失败的 Unit +systemctl list-units --failed + +# 列出所有正在运行的、类型为service的Unit +systemctl list-units --type=service + +# 显示某个 Unit 是否正在运行 +systemctl is-active application.service + +# 显示某个 Unit 是否处于启动失败状态 +systemctl is-failed application.service + +# 显示某个 Unit 服务是否建立了启动链接 +systemctl is-enabled application.service + +# 立即启动一个服务 +sudo systemctl start apache.service + +# 立即停止一个服务 +sudo systemctl stop apache.service + +# 重启一个服务 +sudo systemctl restart apache.service + +# 重新加载一个服务的配置文件 +sudo systemctl reload apache.service + +# 重载所有修改过的配置文件 +sudo systemctl daemon-reload +``` + +**Why choose systemd?** + +**Advanced requirements:** + +- Convenient service runtime log recording for problem analysis +- Service management logs +- Option to restart upon abnormal exit + +The daemon does not meet these advanced requirements. + +`nohup` only logs the service's runtime outputs and errors. + +Only systemd can fulfill all of the above requirements. + +> The default logs are enhanced with timestamps, usernames, service names, PIDs, etc., making them user-friendly. You can view logs of abnormal service exits. Advanced customization is possible through the configuration files in `/lib/systemd/system/`. + +In short, systemd is the current mainstream way to manage backend services on Linux, so I've abandoned `nohup` in my new versions of bash scripts, opting instead for systemd. + +## 2. Prerequisites (Requires root permissions) + +1. Configure `environment.sh` based on the comments. +2. Create a data directory: + +```bash +mkdir -p ${OPENIM_DATA_DIR}/{openim-api,openim-crontask} +``` + +3. Create a bin directory and copy `openim-api` and `openim-crontask` executable files: + +```bash +source ./environment.sh +mkdir -p ${OPENIM_INSTALL_DIR}/bin +cp openim-api openim-crontask ${OPENIM_INSTALL_DIR}/bin +``` + +4. Copy the configuration files of `openim-api` and `openim-crontask` to the `${OPENIM_CONFIG_DIR}` directory: + +```bash +mkdir -p ${OPENIM_CONFIG_DIR} +cp openim-api.yaml openim-crontask.yaml ${OPENIM_CONFIG_DIR} +``` + +## 3. Create `openim-api` systemd unit template file + +For each OpenIM service, we will create a systemd unit template. Follow the steps below for each service: + +Run the following shell script to generate the `openim-api.service.template`: + +```bash +source ./environment.sh +cat > openim-api.service.template < $service.service.template < +``` + +As an example, consider a repository with `main` and `release-v3.1` branches. To apply commit `f` from the `release-v3.1` branch to the `main` branch: + +``` +# Switch to main branch +$ git checkout main + +# Perform cherry-pick +$ git cherry-pick f +``` + +You can also use a branch name instead of a commit hash to cherry-pick the latest commit from that branch. + +```bash +$ git cherry-pick release-v3.1 +``` + +## Applying Multiple Commits + +To apply multiple commits simultaneously: + +```bash +$ git cherry-pick +``` + +To apply a range of consecutive commits: + +```bash +$ git cherry-pick .. +``` + +## Configurations + +Here are some commonly used configurations for `git cherry-pick`: + +- **`-e`, `--edit`**: Open an external editor to modify the commit message. +- **`-n`, `--no-commit`**: Update the working directory and staging area without creating a new commit. +- **`-x`**: Append a reference in the commit message for tracking the source of the cherry-picked commit. +- **`-s`, `--signoff`**: Add a sign-off message at the end of the commit indicating who performed the cherry-pick. +- **`-m parent-number`, `--mainline parent-number`**: When the original commit is a merge of two branches, specify which parent branch's changes should be used. + +## Handling Conflicts + +If conflicts arise during the cherry-pick: + +- **`--continue`**: After resolving conflicts, stage the changes with `git add .` and then continue the cherry-pick process. +- **`--abort`**: Abandon the cherry-pick and revert to the previous state. +- **`--quit`**: Exit the cherry-pick without reverting to the previous state. + +## Applying Commits from Another Repository + +You can also cherry-pick commits from another repository: + +1. Add the external repository as a remote: + + ``` + $ git remote add target git://gitUrl + ``` + +2. Fetch the commits from the remote: + + ``` + $ git fetch target + ``` + +3. Identify the commit hash you wish to cherry-pick: + + ``` + $ git log target/main + ``` + +4. Perform the cherry-pick: + + ``` + $ git cherry-pick + ``` \ No newline at end of file diff --git a/docs/contrib/init_config.md b/docs/contrib/init_config.md new file mode 100644 index 000000000..5e3139dea --- /dev/null +++ b/docs/contrib/init_config.md @@ -0,0 +1,74 @@ +# Init OpenIM Config + +- [Init OpenIM Config](#init-openim-config) + - [Start](#start) + - [Define Automated Configuration](#define-automated-configuration) + - [Define Configuration Variables](#define-configuration-variables) + - [Bash Parsing Features](#bash-parsing-features) + - [Reasons and Advantages of the Design](#reasons-and-advantages-of-the-design) + + +## Start + +With the increasing complexity of software engineering, effective configuration management has become more and more important. Yaml and other configuration files provide the necessary parameters and guidance for systems, but they also impose additional management overhead for developers. This article explores how to automate and optimize configuration management, thereby improving efficiency and reducing the chances of errors. + +First, obtain the OpenIM code through the contributor documentation and initialize it following the steps below. + +## Define Automated Configuration + +We no longer strongly recommend modifying the same configuration file. If you have a new configuration file related to your business, we suggest generating and managing it through automation. + +In the `scripts/init_config.sh` file, we defined some template files. These templates will be automatically generated to the corresponding directories when executing `make init`. + +``` +# Defines an associative array where the keys are the template files and the values are the corresponding output files. +declare -A TEMPLATES=( + ["${OPENIM_ROOT}/scripts/template/config-tmpl/env.template"]="${OPENIM_OUTPUT_SUBPATH}/bin/.env" + ["${OPENIM_ROOT}/scripts/template/config-tmpl/config.yaml"]="${OPENIM_OUTPUT_SUBPATH}/bin/config.yaml" +) +``` + +If you have your new mapping files, you can implement them by appending them to the array. + +Lastly, run: + +``` +./scripts/init_config.sh +``` + +## Define Configuration Variables + +In the `scripts/install/environment.sh` file, we defined many reusable variables for automation convenience. + +In the provided example, the def function is a core element. This function not only provides a concise way to define variables but also offers default value options for each variable. This way, even if a specific variable is not explicitly set in an environment or scenario, it can still have an expected value. + +``` +function def() { + local var_name="$1" + local default_value="$2" + eval "readonly $var_name=\${$var_name:-$default_value}" +} +``` + +### Bash Parsing Features + +Since bash is a parsing script language, it executes commands in the order they appear in the script. This characteristic means we can define commonly used or core variables at the beginning of the script and then reuse or modify them later on. + +For instance, we can initially set a universal password and reuse this password in subsequent variable definitions. + +``` +# Set a consistent password for easy memory +def "PASSWORD" "openIM123" + +# Linux system user for openim +def "LINUX_USERNAME" "openim" +def "LINUX_PASSWORD" "${PASSWORD}" +``` + +## Reasons and Advantages of the Design + +1. **Simplify Configuration Management**: Through automation scripts, we can avoid manual operations and configurations, thus reducing tedious repetitive tasks. +2. **Reduce Errors**: Manually editing yaml or other configuration files can lead to formatting mistakes or typographical errors. Automating with scripts can lower the risk of such errors. +3. **Enhanced Readability**: Using the `def` function and other bash scripting techniques, we can establish a clear, easy-to-read, and maintainable configuration system. +4. **Improved Reusability**: As demonstrated above, we can reuse variables and functions in different parts of the script, reducing redundant code and increasing overall consistency. +5. **Flexible Default Value Mechanism**: By providing default values for variables, we can ensure configurations are complete and consistent across various scenarios, while also offering customization options for advanced users. \ No newline at end of file diff --git a/docs/contrib/install_docker.md b/docs/contrib/install_docker.md new file mode 100644 index 000000000..d2aa27a42 --- /dev/null +++ b/docs/contrib/install_docker.md @@ -0,0 +1,45 @@ +# Install Docker + +The installation command is as follows: + +```bash +$ curl -fsSL https://get.docker.com | bash -s docker --mirror aliyun +`` + +## 2.2 Start Docker + +```bash +$ systemctl start docker +``` + +## 2.3 Test Docker + +```bash +$ docker run hello-world +``` + +## 2.4 Configure Docker Acceleration + +```bash +$ mkdir -p /etc/docker +$ tee /etc/docker/daemon.json <<-'EOF' +{ + "registry-mirrors": ["https://registry.docker-cn.com"] +} +EOF +$ systemctl daemon-reload +$ systemctl restart docker +``` + +## 2.5 Install Docker Compose + +```bash +$ sudo curl -L "https://github.com/docker/compose/releases/download/latest/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose +$ sudo chmod +x /usr/local/bin/docker-compose +``` + +## 2.6 Test Docker Compose + +```bash +$ docker-compose --version +``` diff --git a/docs/contrib/linux_development.md b/docs/contrib/linux_development.md new file mode 100644 index 000000000..e5569a069 --- /dev/null +++ b/docs/contrib/linux_development.md @@ -0,0 +1,137 @@ +# Ubuntu 22.04 OpenIM Project Development Guide + +## TOC +- [Ubuntu 22.04 OpenIM Project Development Guide](#ubuntu-2204-openim-project-development-guide) + - [TOC](#toc) + - [1. Setting Up Ubuntu Server](#1-setting-up-ubuntu-server) + - [1.1 Create `openim` Standard User](#11-create-openim-standard-user) + - [1.2 Setting up the `openim` User's Shell Environment](#12-setting-up-the-openim-users-shell-environment) + - [1.3 Installing Dependencies](#13-installing-dependencies) + +## 1. Setting Up Ubuntu Server + +You can use tools like PuTTY or other SSH clients to log in to your Ubuntu server. Once logged in, a few fundamental configurations are required, such as creating a standard user, adding to sudoers, and setting up the `$HOME/.bashrc` file. The steps are as follows: + +## 1.1 Create `openim` Standard User + +1. Log in to the Ubuntu system as the `root` user and create a standard user. + +Generally, a project will involve multiple developers. Instead of provisioning a server for every developer, many organizations share a single development machine among developers. To simulate this real-world scenario, we'll use a standard user for development. To create the `openim` user: + +``` +bashCopy code# adduser openim # Create the openim user, which developers will use for login and development. +# passwd openim # Set the login password for openim. +``` + +Working with a non-root user ensures the system's safety and is a good practice. It's recommended to avoid using the root user as much as possible during everyday development. + +1. Add to sudoers. + +Often, even standard users need root privileges. Instead of frequently asking the system administrator for the root password, you can add the standard user to the sudoers. This allows them to temporarily gain root access using the sudo command. To add the `openim` user to sudoers: + +``` +bashCopy code +# sed -i '/^root.*ALL=(ALL:ALL).*ALL/a\openim\tALL=(ALL) \tALL' /etc/sudoers +``` + +## 1.2 Setting up the `openim` User's Shell Environment + +1. Log into the Ubuntu system. + +Assuming we're using the **openim** user, log in using PuTTY or other SSH clients. + +1. Configure the `$HOME/.bashrc` file. + +The first step after logging into a new server is to configure the `$HOME/.bashrc` file. It makes the Linux shell more user-friendly by setting environment variables like `LANG` and `PS1`. Here's how the configuration would look: + +``` +bashCopy code# .bashrc + +# User specific aliases and functions + +alias rm='rm -i' +alias cp='cp -i' +alias mv='mv -i' + +# Source global definitions +if [ -f /etc/bashrc ]; then + . /etc/bashrc +fi + +if [ ! -d $HOME/workspace ]; then + mkdir -p $HOME/workspace +fi + +# User specific environment +export LANG="en_US.UTF-8" +export PS1='[\u@dev \W]\$ ' +export WORKSPACE="$HOME/workspace" +export PATH=$HOME/bin:$PATH + +cd $WORKSPACE +``` + +After updating `$HOME/.bashrc`, run the `bash` command to reload the configurations into the current shell. + +## 1.3 Installing Dependencies + +The OpenIM project on Ubuntu may have various dependencies. Some are direct, and others are indirect. Installing these in advance prevents issues like missing packages or compile-time errors later on. + +1. Install dependencies. + +You can use the `apt` command to install the required tools on Ubuntu: + +``` +bashCopy code$ sudo apt-get update +$ sudo apt-get install build-essential autoconf automake cmake perl libcurl4-gnutls-dev libtool gcc g++ glibc-doc-reference zlib1g-dev git-lfs telnet lrzsz jq libexpat1-dev libssl-dev +$ sudo apt install libcurl4-openssl-dev +``` + +1. Install Git. + +A higher version of Git ensures compatibility with certain commands like `git fetch --unshallow`. To install a recent version: + +``` +bashCopy code$ cd /tmp +$ wget --no-check-certificate https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.36.1.tar.gz +$ tar -xvzf git-2.36.1.tar.gz +$ cd git-2.36.1/ +$ ./configure +$ make +$ sudo make install +$ git --version +``` + +Then, add Git's binary directory to the `PATH`: + +``` +bashCopy code +$ echo 'export PATH=/usr/local/libexec/git-core:$PATH' >> $HOME/.bashrc +``` + +1. Configure Git. + +To set up Git: + +``` +bashCopy code$ git config --global user.name "Your Name" +$ git config --global user.email "your_email@example.com" +$ git config --global credential.helper store +$ git config --global core.longpaths true +``` + +Other Git configurations include: + +``` +bashCopy code +$ git config --global core.quotepath off +``` + +And for handling larger files: + +``` +bashCopy code +$ git lfs install --skip-repo +``` + +By following the steps in this guide, your Ubuntu 22.04 server should now be set up and ready for OpenIM project development. \ No newline at end of file diff --git a/docs/contrib/local_actions.md b/docs/contrib/local_actions.md new file mode 100644 index 000000000..f28bbe72f --- /dev/null +++ b/docs/contrib/local_actions.md @@ -0,0 +1,14 @@ +# act + +Run your [GitHub Actions](https://developer.github.com/actions/) locally! Why would you want to do this? Two reasons: + +- **Fast Feedback** - Rather than having to commit/push every time you want to test out the changes you are making to your `.github/workflows/` files (or for any changes to embedded GitHub actions), you can use `act` to run the actions locally. The [environment variables](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables) and [filesystem](https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners#filesystems-on-github-hosted-runners) are all configured to match what GitHub provides. +- **Local Task Runner** - I love [make](https://en.wikipedia.org/wiki/Make_(software)). However, I also hate repeating myself. With `act`, you can use the GitHub Actions defined in your `.github/workflows/` to replace your `Makefile`! + +## install act + ++ [https://github.com/nektos/act](https://github.com/nektos/act) + +```bash +curl -s https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash +··· \ No newline at end of file diff --git a/docs/contrib/protoc_tools.md b/docs/contrib/protoc_tools.md new file mode 100644 index 000000000..66f2e9dec --- /dev/null +++ b/docs/contrib/protoc_tools.md @@ -0,0 +1,60 @@ +# OpenIM Protoc Tool + +## Introduction + +OpenIM is passionate about ensuring that its suite of tools is custom-tailored to cater to the unique needs of its users. That commitment led us to develop and release our custom Protoc tool, version v1.0.0. + +### Why a Custom Version? + +There are several reasons to choose our custom Protoc tool over generic open-source versions: + +- **Specialized Features**: OpenIM's Protoc tool has been enriched with features and plugins that are optimized for the OpenIM ecosystem. This makes it more aligned with the needs of OpenIM users. +- **Optimized Performance**: Built from the ground up with OpenIM's infrastructure in mind, our tool guarantees faster and more efficient operations. +- **Enhanced Compatibility**: Our Protoc tool ensures full compatibility with OpenIM's offerings, minimizing potential conflicts and integration challenges. +- **Rich Output Support**: Unlike generic tools, our custom tool provides a wide array of output options including C++, C#, Java, Kotlin, Objective-C, PHP, Python, Ruby, and more. This allows developers to generate code for their preferred platform with ease. + +## Download + ++ https://github.com/OpenIMSDK/Open-IM-Protoc + +Access the official release of the Protoc tool on the OpenIM repository here: [OpenIM Protoc Tool v1.0.0 Release](https://github.com/OpenIMSDK/Open-IM-Protoc/releases/tag/v1.0.0) + +### Direct Download Links: + +- **Windows**: [Download for Windows](https://github.com/OpenIMSDK/Open-IM-Protoc/releases/download/v1.0.0/windows.zip) +- **Linux**: [Download for Linux](https://github.com/OpenIMSDK/Open-IM-Protoc/releases/download/v1.0.0/linux.zip) + +## Installation + +For Windows: + +1. Navigate to the Windows download link provided above and download the version suitable for your system. +2. Extract the contents of the zip file. +3. Add the path of the extracted tool to your `PATH` environment variable to run the Protoc tool directly from the command line. + +For Linux: + +1. Navigate to the Linux download link provided above and download the version suitable for your system. +2. Extract the contents of the zip file. +3. Use `chmod +x ./*` to make the extracted files executable. +4. Add the path of the extracted tool to your `PATH` environment variable to run the Protoc tool directly from the command line. + +## Usage + +The OpenIM Protoc tool provides a multitude of options for parsing `.proto` files and generating output: + +``` +bashCopy code +./protoc [OPTION] PROTO_FILES +``` + +Some of the key options include: + +- `--proto_path=PATH`: Specify the directory to search for imports. +- `--version`: Show version info. +- `--encode=MESSAGE_TYPE`: Convert a text-format message of a given type from standard input to binary on standard output. +- `--decode=MESSAGE_TYPE`: Convert a binary message of a given type from standard input to text format on standard output. +- `--cpp_out=OUT_DIR`: Generate C++ header and source. +- `--java_out=OUT_DIR`: Generate Java source file. + +... and many more. For a full list of options, run `./protoc --help` or refer to the official documentation. \ No newline at end of file diff --git a/docs/contrib/util_go.md b/docs/contrib/util_go.md new file mode 100644 index 000000000..4126aa97c --- /dev/null +++ b/docs/contrib/util_go.md @@ -0,0 +1,8 @@ +# utils go + ++ [toold readme](https://github.com/OpenIMSDK/Open-IM-Server/tree/main/tools) + +about scripts fix: +``` +"${OPENIM-ROOT}/_output/bin/tools/${platform}/${lookfor}" +``` diff --git a/docs/contrib/util_makefile.md b/docs/contrib/util_makefile.md new file mode 100644 index 000000000..e0331f50e --- /dev/null +++ b/docs/contrib/util_makefile.md @@ -0,0 +1,90 @@ +# Open-IM-Server Development Tools Guide + +- [Open-IM-Server Development Tools Guide](#open-im-server-development-tools-guide) + - [Introduction](#introduction) + - [Getting Started](#getting-started) + - [Toolset Categories](#toolset-categories) + - [Installation Commands](#installation-commands) + - [Basic Installation](#basic-installation) + - [Individual Tool Installation](#individual-tool-installation) + - [Tool Verification](#tool-verification) + - [Detailed Tool Descriptions](#detailed-tool-descriptions) + - [Best Practices](#best-practices) + - [Conclusion](#conclusion) + + +## Introduction + +Open-IM-Server boasts a robust set of tools encapsulated within its Makefile system, designed to ease development, code formatting, and tool management. This guide aims to familiarize developers with the features and usage of the Makefile toolset provided within the Open-IM-Server project. + +## Getting Started + +Executing `make tools` ensures verification and installation of the default tools: + +- golangci-lint +- goimports +- addlicense +- deepcopy-gen +- conversion-gen +- ginkgo +- go-junit-report +- go-gitlint + +The installation path is situated at `/root/workspaces/openim/Open-IM-Server/_output/tools/`. + +## Toolset Categories + +The Makefile logically groups tools into different categories for better management: + +- **Development Tools**: `BUILD_TOOLS` +- **Code Analysis Tools**: `ANALYSIS_TOOLS` +- **Code Generation Tools**: `GENERATION_TOOLS` +- **Testing Tools**: `TEST_TOOLS` +- **Version Control Tools**: `VERSION_CONTROL_TOOLS` +- **Utility Tools**: `UTILITY_TOOLS` +- **Tencent Cloud Object Storage Tools**: `COS_TOOLS` + +## Installation Commands + +1. **golangci-lint**: high performance Go code linter with integration of multiple inspection tools. +2. **goimports**: Used to format Go source files and automatically add or remove imports. +3. **addlicense**: Adds a license header to the source file. +4. **deepcopy-gen and conversions-gen **: Generate deepcopy and conversion functionality. +5. **ginkgo**: Testing framework for Go. +6. **go-junit-report**: Converts Go test output to junit xml format. +7. **go-gitlint**: For checking git commit information. ... (And so on, list all the tools according to the `make tools.help` output above)... + + + +### Basic Installation + +- `tools.install`: Installs tools mentioned in the `BUILD_TOOLS` list. +- `tools.install-all`: Installs all tools from the `ALL_TOOLS` list. + +### Individual Tool Installation + +- `tools.install.%`: Installs a single tool in the `$GOBIN/` directory. +- `tools.install-all.%`: Parallelly installs an individual tool located in `./tools/*`. + +### Tool Verification + +- `tools.verify.%`: Checks if a specific tool is installed, and if not, installs it. + +## Detailed Tool Descriptions + +The following commands serve the purpose of installing particular development tools: + +- `install.golangci-lint`: Installs `golangci-lint`. +- `install.addlicense`: Installs `addlicense`. ... (and so on for every tool as mentioned in the provided Makefile source)... + +The commands primarily leverage Go's `install` operation, fetching and installing tools from their respective repositories. This method is especially convenient as it auto-handles dependencies and installation paths. For tools not written directly with Go (like `install.coscli`), other installation methods like wget or pip are employed. + +## Best Practices + +1. **Regular Updates**: To ensure tools are up-to-date, periodically run the `make tools` command. +2. **Individual Tools**: If only specific tools are required, employ the `make install.` command for individual installations. +3. **Verification**: Before code submissions, use the `make tools.verify.%` command to guarantee that all necessary tools are present and up-to-date. + +## Conclusion + +The Makefile provided by Open-IM-Server presents a centralized approach to manage and install all necessary tools during the development process. It ensures that all developers employ consistent tool versions, reducing potential issues due to version disparities. Whether you're a maintainer or a contributor to the Open-IM-Server project, understanding the workings of this Makefile will significantly enhance your developmental efficiency. diff --git a/docs/contrib/util_scripts.md b/docs/contrib/util_scripts.md new file mode 100644 index 000000000..0bf6f23e5 --- /dev/null +++ b/docs/contrib/util_scripts.md @@ -0,0 +1,248 @@ +# OpenIM Bash Utility Script + +This script offers a variety of utilities and helpers to enhance and simplify operations related to the OpenIM project. + +## Table of Contents + +- [OpenIM Bash Utility Script](#openim-bash-utility-script) + - [Table of Contents](#table-of-contents) + - [brief descriptions of each function](#brief-descriptions-of-each-function) + - [Introduction](#introduction) + - [Usage](#usage) + - [SSH Key Setup](#ssh-key-setup) + - [openim::util::ensure-gnu-sed](#openimutilensure-gnu-sed) + - [openim::util::ensure-gnu-date](#openimutilensure-gnu-date) + - [openim::util::check-file-in-alphabetical-order](#openimutilcheck-file-in-alphabetical-order) + - [openim::util::require-jq](#openimutilrequire-jq) + - [openim::util::md5](#openimutilmd5) + - [openim::util::read-array](#openimutilread-array) + - [Color Definitions](#color-definitions) + - [openim::util::desc and related functions](#openimutildesc-and-related-functions) + - [openim::util::onCtrlC](#openimutilonctrlc) + - [openim::util::list-to-string](#openimutillist-to-string) + - [openim::util::remove-space](#openimutilremove-space) + - [openim::util::gencpu](#openimutilgencpu) + - [openim::util::gen-os-arch](#openimutilgen-os-arch) + - [openim::util::download-file](#openimutildownload-file) + - [openim::util::get-public-ip](#openimutilget-public-ip) + - [openim::util::extract-tarball](#openimutilextract-tarball) + - [openim::util::check-port-open](#openimutilcheck-port-open) + - [openim::util::file-lines-count](#openimutilfile-lines-count) + + +## brief descriptions of each function + +**Englist:** +1. `openim::util::ensure-gnu-sed` - Determines if GNU version of `sed` exists on the system and sets its name. +2. `openim::util::ensure-gnu-date` - Determines if GNU version of `date` exists on the system and sets its name. +3. `openim::util::check-file-in-alphabetical-order` - Checks if a file is sorted in alphabetical order. +4. `openim::util::require-jq` - Checks if `jq` is installed. +5. `openim::util::md5` - Outputs the MD5 hash of a file. +6. `openim::util::read-array` - Reads content from standard input into an array. +7. `openim::util::desc` - Displays descriptive information. +8. `openim::util::run::prompt` - Displays a prompt. +9. `openim::util::run::maybe-first-prompt` - Possibly displays the first prompt based on whether it's started or not. +10. `openim::util::run` - Executes a command and captures its output. +11. `openim::util::run::relative` - Returns paths relative to the current script. +12. `openim::util::onCtrlC` - Performs an action when Ctrl+C is pressed. +13. `openim::util::list-to-string` - Converts a list into a string. +14. `openim::util::remove-space` - Removes spaces from a string. +15. `openim::util::gencpu` - Retrieves CPU information. +16. `openim::util::gen-os-arch` - Generates a repository directory based on the operating system and architecture. +17. `openim::util::download-file` - Downloads a file from a URL. +18. `openim::util::get-public-ip` - Retrieves the public IP address of the machine. +19. `openim::util::extract-tarball` - Extracts a tarball to a specified directory. +20. `openim::util::check-port-open` - Checks if a given port is open on the machine. +21. `openim::util::file-lines-count` - Counts the number of lines in a file. + + + +## Introduction + +This script is mainly used to validate whether the code is correctly formatted by `gofmt`. Apart from that, it offers utilities like setting up SSH keys, various wait conditions, host and platform detection, documentation generation, etc. + +## Usage + +### SSH Key Setup + +To set up an SSH key: + +```bash +#1. Write IPs in a file, one IP per line. Let's name it hosts-file. +#2. Modify the default username and password in the script. +hosts-file-path="path/to/your/hosts/file" +openim:util::setup_ssh_key_copy "$hosts-file-path" "root" "123" +``` + +## openim::util::ensure-gnu-sed + +Ensures the presence of the GNU version of the `sed` command. Different operating systems may have variations of the `sed` command, and this utility function is used to make sure the script uses the GNU version. If it finds the GNU `sed`, it sets the `SED` variable accordingly. If not found, it checks for `gsed`, which is usually the name of GNU `sed` on macOS. If neither is found, an error message is displayed. + + + +## openim::util::ensure-gnu-date + +Similar to the function for `sed`, this function ensures the script uses the GNU version of the `date` command. If it identifies the GNU `date`, it sets the `DATE` variable. On macOS, it looks for `gdate` as an alternative. In the absence of both, an error message is recommended. + + + +## openim::util::check-file-in-alphabetical-order + +This function checks if the contents of a given file are sorted in alphabetical order. If not, it provides a command suggestion for the user to sort the file correctly. + + + +## openim::util::require-jq + +Verifies the installation of `jq`, a popular command-line JSON parser. If it's not present, a prompt to install it is displayed. + + + +## openim::util::md5 + +A cross-platform function that computes the MD5 hash of its input. This function takes into account the differences in the `md5` command between macOS and Linux. + + + +## openim::util::read-array + +A function designed to read from stdin and populate an array, line by line. It's provided as an alternative to `mapfile -t` and is compatible with bash 3. + + + +## Color Definitions + +The script also defines a set of colors to enhance its console output. These include colors like red, yellow, green, blue, cyan, etc., which can be used for better user experience and clear logs. + + + +## openim::util::desc and related functions + +These functions seem to aid in building interactive demonstrations or tutorials in the terminal. They use the `pv` utility to control the display rate of the output, emulating typing. There's also functionality to handle user prompts and execute commands while capturing their output. + + + +## openim::util::onCtrlC + +Handles the `CTRL+C` command. It terminates background processes of the script when the user interrupts it using `CTRL+C`. + + + +## openim::util::list-to-string + +Transforms a list format (like `[10023, 2323, 3434]`) to a space-separated string (`10023 2323 3434`). Also removes unnecessary spaces and characters. + + + +## openim::util::remove-space + +Removes spaces from a given string. + + + +## openim::util::gencpu + +Fetches the number of CPUs using the `lscpu` command. + + + +## openim::util::gen-os-arch + +Identifies the operating system and architecture of the system running the script. This is useful to determine directories or binaries specific to that OS and architecture. + + + +## openim::util::download-file + +This function can be used to download a file from a URL. If `curl` is available, it uses `curl`. If not, it falls back to `wget`. + +```bash +function openim::util::download-file() { + local url="$1" + local dest="$2" + + if command -v curl &>/dev/null; then + curl -L "${url}" -o "${dest}" + elif command -v wget &>/dev/null; then + wget "${url}" -O "${dest}" + else + openim::log::error "Neither curl nor wget available. Cannot download file." + return 1 + fi +} +``` + + + +## openim::util::get-public-ip + +Fetches the public IP address of the machine. + +```bash +function openim::util::get-public-ip() { + if command -v curl &>/dev/null; then + curl -s https://ipinfo.io/ip + elif command -v wget &>/dev/null; then + wget -qO- https://ipinfo.io/ip + else + openim::log::error "Neither curl nor wget available. Cannot fetch public IP." + return 1 + fi +} +``` + + + +## openim::util::extract-tarball + +This function extracts a tarball to a specified directory. + +```bash +function openim::util::extract-tarball() { + local tarball="$1" + local dest="$2" + + mkdir -p "${dest}" + tar -xzf "${tarball}" -C "${dest}" +} +``` + + + +## openim::util::check-port-open + +Checks if a given port is open on the local machine. + +```bash +function openim::util::check-port-open() { + local port="$1" + if command -v nc &>/dev/null; then + echo -n > /dev/tcp/127.0.0.1/"${port}" 2>&1 + return $? + elif command -v telnet &>/dev/null; then + telnet 127.0.0.1 "${port}" 2>&1 | grep -q "Connected" + return $? + else + openim::log::error "Neither nc nor telnet available. Cannot check port." + return 1 + fi +} +``` + + + +## openim::util::file-lines-count + +Counts the number of lines in a file. + +```bash +function openim::util::file-lines-count() { + local file="$1" + if [[ -f "${file}" ]]; then + wc -l < "${file}" + else + openim::log::error "File does not exist: ${file}" + return 1 + fi +} +``` \ No newline at end of file diff --git a/docs/conversions/bash_log.md b/docs/conversions/bash_log.md new file mode 100644 index 000000000..86acb1d33 --- /dev/null +++ b/docs/conversions/bash_log.md @@ -0,0 +1,47 @@ +## OpenIM Logging System: Design and Usage + +**PATH:** `scripts/lib/logging.sh` + +### Introduction + +OpenIM, an intricate project, requires a robust logging mechanism to diagnose issues, maintain system health, and provide insights. A custom-built logging system embedded within OpenIM ensures consistent and structured logs. Let's delve into the design of this logging system and understand its various functions and their usage scenarios. + +### Design Overview + +1. **Initialization**: The system begins by determining the verbosity level through the `OPENIM_VERBOSE` variable. If it's not set, a default value of 5 is assigned. This verbosity level dictates the depth of the log details. +2. **Log File Setup**: Logs are stored in the directory specified by `OPENIM_OUTPUT`. If this variable isn't explicitly set, it defaults to the `_output` directory relative to the script location. Each log file is named based on the date to facilitate easy identification. +3. **Logging Function**: The `echo_log()` function plays a pivotal role by writing messages to both the console (stdout) and the log file. +4. **Logging to a file**: The `echo_log()` function writes to the log file by appending the message to the file. It also adds a timestamp to the message. path: `_output/logs/*`, Enable logging by default. Set to false to disable. If you wish to turn off output to log files set `ENABLE_LOGGING=flase`. + +### Key Functions & Their Usages + +1. **Error Handling**: + - `openim::log::errexit()`: Activated when a command exits with an error. It prints a call tree showing the sequence of functions leading to the error and then calls `openim::log::error_exit()` with relevant information. + - `openim::log::install_errexit()`: Sets up the trap for catching errors and ensures that the error handler (`errexit`) gets propagated to various script constructs like functions, expansions, and subshells. +2. **Logging Levels**: + - `openim::log::error()`: Logs error messages with a timestamp. The log message starts with '!!!' to indicate its severity. + - `openim::log::info()`: Provides informational messages. The display of these messages is governed by the verbosity level (`OPENIM_VERBOSE`). + - `openim::log::progress()`: Designed for logging progress messages or creating progress bars. + - `openim::log::status()`: Logs status messages with a timestamp, prefixing each entry with '+++' for easy identification. + - `openim::log::success()`: Highlights successful operations with a bright green prefix. It's ideal for visually signifying operations that completed successfully. +3. **Exit and Stack Trace**: + - `openim::log::error_exit()`: Logs an error message, dumps the call stack, and exits the script with a specified exit code. + - `openim::log::stack()`: Prints out a stack trace, showing the call hierarchy leading to the point where this function was invoked. +4. **Usage Information**: + - `openim::log::usage() & openim::log::usage_from_stdin()`: Both functions provide a mechanism to display usage instructions. The former accepts arguments directly, while the latter reads them from stdin. +5. **Test Function**: + - `openim::log::test_log()`: This function is a test suite to verify that all logging functions are operating as expected. + +### Usage Scenario + +Imagine a situation where an OpenIM operation fails, and you need to ascertain the cause. With the logging system in place, you can: + +- Check the log file for the specific day to find error messages with the '!!!' prefix. +- View the call tree and stack trace to trace back the sequence of operations leading to the failure. +- Use the verbosity level to filter out unnecessary details and focus on the crux of the issue. + +This systematic and structured approach greatly simplifies the debugging process, making system maintenance more efficient. + +### Conclusion + +OpenIM's logging system is a testament to the importance of structured and detailed logging in complex projects. By using this logging mechanism, developers and system administrators can streamline troubleshooting and ensure the seamless operation of the OpenIM project. \ No newline at end of file diff --git a/docs/contrib/cicd-actions.md b/docs/conversions/cicd_actions.md similarity index 100% rename from docs/contrib/cicd-actions.md rename to docs/conversions/cicd_actions.md diff --git a/docs/conversions/go_code.md b/docs/conversions/go_code.md index 6e1adf06d..aeb1a02ad 100644 --- a/docs/conversions/go_code.md +++ b/docs/conversions/go_code.md @@ -39,9 +39,6 @@ import ( _ "github.com/jinzhu/gorm/dialects/mysql" // inner package -v1 "github.com/marmotedu/api/apiserver/v1" -metav1 "github.com/marmotedu/apimachinery/pkg/meta/v1" -"github.com/marmotedu/iam/pkg/cli/genericclioptions" ) ``` diff --git a/go.work b/go.work index 757933536..ce1770c8e 100644 --- a/go.work +++ b/go.work @@ -2,7 +2,10 @@ go 1.20 use ( . - ./tools/component + ./test/typecheck + ./tools/changelog + ./tools/imctl ./tools/infra ./tools/ncpu + ./tools/yamlfmt ) diff --git a/go.work.sum b/go.work.sum deleted file mode 100644 index 89e737b5c..000000000 --- a/go.work.sum +++ /dev/null @@ -1,311 +0,0 @@ -cloud.google.com/go/accessapproval v1.7.1 h1:/5YjNhR6lzCvmJZAnByYkfEgWjfAKwYP6nkuTk6nKFE= -cloud.google.com/go/accessapproval v1.7.1/go.mod h1:JYczztsHRMK7NTXb6Xw+dwbs/WnOJxbo/2mTI+Kgg68= -cloud.google.com/go/accesscontextmanager v1.8.1 h1:WIAt9lW9AXtqw/bnvrEUaE8VG/7bAAeMzRCBGMkc4+w= -cloud.google.com/go/accesscontextmanager v1.8.1/go.mod h1:JFJHfvuaTC+++1iL1coPiG1eu5D24db2wXCDWDjIrxo= -cloud.google.com/go/aiplatform v1.48.0 h1:M5davZWCTzE043rJCn+ZLW6hSxfG1KAx4vJTtas2/ec= -cloud.google.com/go/aiplatform v1.48.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA= -cloud.google.com/go/analytics v0.21.3 h1:TFBC1ZAqX9/jL56GEXdLrVe5vT3I22bDVWyDwZX4IEg= -cloud.google.com/go/analytics v0.21.3/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo= -cloud.google.com/go/apigateway v1.6.1 h1:aBSwCQPcp9rZ0zVEUeJbR623palnqtvxJlUyvzsKGQc= -cloud.google.com/go/apigateway v1.6.1/go.mod h1:ufAS3wpbRjqfZrzpvLC2oh0MFlpRJm2E/ts25yyqmXA= -cloud.google.com/go/apigeeconnect v1.6.1 h1:6u/jj0P2c3Mcm+H9qLsXI7gYcTiG9ueyQL3n6vCmFJM= -cloud.google.com/go/apigeeconnect v1.6.1/go.mod h1:C4awq7x0JpLtrlQCr8AzVIzAaYgngRqWf9S5Uhg+wWs= -cloud.google.com/go/apigeeregistry v0.7.1 h1:hgq0ANLDx7t2FDZDJQrCMtCtddR/pjCqVuvQWGrQbXw= -cloud.google.com/go/apigeeregistry v0.7.1/go.mod h1:1XgyjZye4Mqtw7T9TsY4NW10U7BojBvG4RMD+vRDrIw= -cloud.google.com/go/appengine v1.8.1 h1:J+aaUZ6IbTpBegXbmEsh8qZZy864ZVnOoWyfa1XSNbI= -cloud.google.com/go/appengine v1.8.1/go.mod h1:6NJXGLVhZCN9aQ/AEDvmfzKEfoYBlfB80/BHiKVputY= -cloud.google.com/go/area120 v0.8.1 h1:wiOq3KDpdqXmaHzvZwKdpoM+3lDcqsI2Lwhyac7stss= -cloud.google.com/go/area120 v0.8.1/go.mod h1:BVfZpGpB7KFVNxPiQBuHkX6Ed0rS51xIgmGyjrAfzsg= -cloud.google.com/go/artifactregistry v1.14.1 h1:k6hNqab2CubhWlGcSzunJ7kfxC7UzpAfQ1UPb9PDCKI= -cloud.google.com/go/artifactregistry v1.14.1/go.mod h1:nxVdG19jTaSTu7yA7+VbWL346r3rIdkZ142BSQqhn5E= -cloud.google.com/go/asset v1.14.1 h1:vlHdznX70eYW4V1y1PxocvF6tEwxJTTarwIGwOhFF3U= -cloud.google.com/go/asset v1.14.1/go.mod h1:4bEJ3dnHCqWCDbWJ/6Vn7GVI9LerSi7Rfdi03hd+WTQ= -cloud.google.com/go/assuredworkloads v1.11.1 h1:yaO0kwS+SnhVSTF7BqTyVGt3DTocI6Jqo+S3hHmCwNk= -cloud.google.com/go/assuredworkloads v1.11.1/go.mod h1:+F04I52Pgn5nmPG36CWFtxmav6+7Q+c5QyJoL18Lry0= -cloud.google.com/go/automl v1.13.1 h1:iP9iQurb0qbz+YOOMfKSEjhONA/WcoOIjt6/m+6pIgo= -cloud.google.com/go/automl v1.13.1/go.mod h1:1aowgAHWYZU27MybSCFiukPO7xnyawv7pt3zK4bheQE= -cloud.google.com/go/baremetalsolution v1.1.1 h1:0Ge9PQAy6cZ1tRrkc44UVgYV15nw2TVnzJzYsMHXF+E= -cloud.google.com/go/baremetalsolution v1.1.1/go.mod h1:D1AV6xwOksJMV4OSlWHtWuFNZZYujJknMAP4Qa27QIA= -cloud.google.com/go/batch v1.3.1 h1:uE0Q//W7FOGPjf7nuPiP0zoE8wOT3ngoIO2HIet0ilY= -cloud.google.com/go/batch v1.3.1/go.mod h1:VguXeQKXIYaeeIYbuozUmBR13AfL4SJP7IltNPS+A4A= -cloud.google.com/go/beyondcorp v1.0.0 h1:VPg+fZXULQjs8LiMeWdLaB5oe8G9sEoZ0I0j6IMiG1Q= -cloud.google.com/go/beyondcorp v1.0.0/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4= -cloud.google.com/go/bigquery v1.53.0 h1:K3wLbjbnSlxhuG5q4pntHv5AEbQM1QqHKGYgwFIqOTg= -cloud.google.com/go/bigquery v1.53.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4= -cloud.google.com/go/billing v1.16.0 h1:1iktEAIZ2uA6KpebC235zi/rCXDdDYQ0bTXTNetSL80= -cloud.google.com/go/billing v1.16.0/go.mod h1:y8vx09JSSJG02k5QxbycNRrN7FGZB6F3CAcgum7jvGA= -cloud.google.com/go/binaryauthorization v1.6.1 h1:cAkOhf1ic92zEN4U1zRoSupTmwmxHfklcp1X7CCBKvE= -cloud.google.com/go/binaryauthorization v1.6.1/go.mod h1:TKt4pa8xhowwffiBmbrbcxijJRZED4zrqnwZ1lKH51U= -cloud.google.com/go/certificatemanager v1.7.1 h1:uKsohpE0hiobx1Eak9jNcPCznwfB6gvyQCcS28Ah9E8= -cloud.google.com/go/certificatemanager v1.7.1/go.mod h1:iW8J3nG6SaRYImIa+wXQ0g8IgoofDFRp5UMzaNk1UqI= -cloud.google.com/go/channel v1.16.0 h1:dqRkK2k7Ll/HHeYGxv18RrfhozNxuTJRkspW0iaFZoY= -cloud.google.com/go/channel v1.16.0/go.mod h1:eN/q1PFSl5gyu0dYdmxNXscY/4Fi7ABmeHCJNf/oHmc= -cloud.google.com/go/cloudbuild v1.13.0 h1:YBbAWcvE4x6xPWTyS+OU4eiUpz5rCS3VCM/aqmfddPA= -cloud.google.com/go/cloudbuild v1.13.0/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU= -cloud.google.com/go/clouddms v1.6.1 h1:rjR1nV6oVf2aNNB7B5uz1PDIlBjlOiBgR+q5n7bbB7M= -cloud.google.com/go/clouddms v1.6.1/go.mod h1:Ygo1vL52Ov4TBZQquhz5fiw2CQ58gvu+PlS6PVXCpZI= -cloud.google.com/go/cloudtasks v1.12.1 h1:cMh9Q6dkvh+Ry5LAPbD/U2aw6KAqdiU6FttwhbTo69w= -cloud.google.com/go/cloudtasks v1.12.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM= -cloud.google.com/go/contactcenterinsights v1.10.0 h1:YR2aPedGVQPpFBZXJnPkqRj8M//8veIZZH5ZvICoXnI= -cloud.google.com/go/contactcenterinsights v1.10.0/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM= -cloud.google.com/go/container v1.24.0 h1:N51t/cgQJFqDD/W7Mb+IvmAPHrf8AbPx7Bb7aF4lROE= -cloud.google.com/go/container v1.24.0/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4= -cloud.google.com/go/containeranalysis v0.10.1 h1:SM/ibWHWp4TYyJMwrILtcBtYKObyupwOVeceI9pNblw= -cloud.google.com/go/containeranalysis v0.10.1/go.mod h1:Ya2jiILITMY68ZLPaogjmOMNkwsDrWBSTyBubGXO7j0= -cloud.google.com/go/datacatalog v1.16.0 h1:qVeQcw1Cz93/cGu2E7TYUPh8Lz5dn5Ws2siIuQ17Vng= -cloud.google.com/go/datacatalog v1.16.0/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4= -cloud.google.com/go/dataflow v0.9.1 h1:VzG2tqsk/HbmOtq/XSfdF4cBvUWRK+S+oL9k4eWkENQ= -cloud.google.com/go/dataflow v0.9.1/go.mod h1:Wp7s32QjYuQDWqJPFFlnBKhkAtiFpMTdg00qGbnIHVw= -cloud.google.com/go/dataform v0.8.1 h1:xcWso0hKOoxeW72AjBSIp/UfkvpqHNzzS0/oygHlcqY= -cloud.google.com/go/dataform v0.8.1/go.mod h1:3BhPSiw8xmppbgzeBbmDvmSWlwouuJkXsXsb8UBih9M= -cloud.google.com/go/datafusion v1.7.1 h1:eX9CZoyhKQW6g1Xj7+RONeDj1mV8KQDKEB9KLELX9/8= -cloud.google.com/go/datafusion v1.7.1/go.mod h1:KpoTBbFmoToDExJUso/fcCiguGDk7MEzOWXUsJo0wsI= -cloud.google.com/go/datalabeling v0.8.1 h1:zxsCD/BLKXhNuRssen8lVXChUj8VxF3ofN06JfdWOXw= -cloud.google.com/go/datalabeling v0.8.1/go.mod h1:XS62LBSVPbYR54GfYQsPXZjTW8UxCK2fkDciSrpRFdY= -cloud.google.com/go/dataplex v1.9.0 h1:yoBWuuUZklYp7nx26evIhzq8+i/nvKYuZr1jka9EqLs= -cloud.google.com/go/dataplex v1.9.0/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE= -cloud.google.com/go/dataproc/v2 v2.0.1 h1:4OpSiPMMGV3XmtPqskBU/RwYpj3yMFjtMLj/exi425Q= -cloud.google.com/go/dataproc/v2 v2.0.1/go.mod h1:7Ez3KRHdFGcfY7GcevBbvozX+zyWGcwLJvvAMwCaoZ4= -cloud.google.com/go/dataqna v0.8.1 h1:ITpUJep04hC9V7C+gcK390HO++xesQFSUJ7S4nSnF3U= -cloud.google.com/go/dataqna v0.8.1/go.mod h1:zxZM0Bl6liMePWsHA8RMGAfmTG34vJMapbHAxQ5+WA8= -cloud.google.com/go/datastore v1.13.0 h1:ktbC66bOQB3HJPQe8qNI1/aiQ77PMu7hD4mzE6uxe3w= -cloud.google.com/go/datastore v1.13.0/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70= -cloud.google.com/go/datastream v1.10.0 h1:ra/+jMv36zTAGPfi8TRne1hXme+UsKtdcK4j6bnqQiw= -cloud.google.com/go/datastream v1.10.0/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q= -cloud.google.com/go/deploy v1.13.0 h1:A+w/xpWgz99EYzB6e31gMGAI/P5jTZ2UO7veQK5jQ8o= -cloud.google.com/go/deploy v1.13.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g= -cloud.google.com/go/dialogflow v1.40.0 h1:sCJbaXt6ogSbxWQnERKAzos57f02PP6WkGbOZvXUdwc= -cloud.google.com/go/dialogflow v1.40.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4= -cloud.google.com/go/dlp v1.10.1 h1:tF3wsJ2QulRhRLWPzWVkeDz3FkOGVoMl6cmDUHtfYxw= -cloud.google.com/go/dlp v1.10.1/go.mod h1:IM8BWz1iJd8njcNcG0+Kyd9OPnqnRNkDV8j42VT5KOI= -cloud.google.com/go/documentai v1.22.0 h1:dW8ex9yb3oT9s1yD2+yLcU8Zq15AquRZ+wd0U+TkxFw= -cloud.google.com/go/documentai v1.22.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E= -cloud.google.com/go/domains v0.9.1 h1:rqz6KY7mEg7Zs/69U6m6LMbB7PxFDWmT3QWNXIqhHm0= -cloud.google.com/go/domains v0.9.1/go.mod h1:aOp1c0MbejQQ2Pjf1iJvnVyT+z6R6s8pX66KaCSDYfE= -cloud.google.com/go/edgecontainer v1.1.1 h1:zhHWnLzg6AqzE+I3gzJqiIwHfjEBhWctNQEzqb+FaRo= -cloud.google.com/go/edgecontainer v1.1.1/go.mod h1:O5bYcS//7MELQZs3+7mabRqoWQhXCzenBu0R8bz2rwk= -cloud.google.com/go/errorreporting v0.3.0 h1:kj1XEWMu8P0qlLhm3FwcaFsUvXChV/OraZwA70trRR0= -cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= -cloud.google.com/go/essentialcontacts v1.6.2 h1:OEJ0MLXXCW/tX1fkxzEZOsv/wRfyFsvDVNaHWBAvoV0= -cloud.google.com/go/essentialcontacts v1.6.2/go.mod h1:T2tB6tX+TRak7i88Fb2N9Ok3PvY3UNbUsMag9/BARh4= -cloud.google.com/go/eventarc v1.13.0 h1:xIP3XZi0Xawx8DEfh++mE2lrIi5kQmCr/KcWhJ1q0J4= -cloud.google.com/go/eventarc v1.13.0/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI= -cloud.google.com/go/filestore v1.7.1 h1:Eiz8xZzMJc5ppBWkuaod/PUdUZGCFR8ku0uS+Ah2fRw= -cloud.google.com/go/filestore v1.7.1/go.mod h1:y10jsorq40JJnjR/lQ8AfFbbcGlw3g+Dp8oN7i7FjV4= -cloud.google.com/go/functions v1.15.1 h1:LtAyqvO1TFmNLcROzHZhV0agEJfBi+zfMZsF4RT/a7U= -cloud.google.com/go/functions v1.15.1/go.mod h1:P5yNWUTkyU+LvW/S9O6V+V423VZooALQlqoXdoPz5AE= -cloud.google.com/go/gkebackup v1.3.0 h1:lgyrpdhtJKV7l1GM15YFt+OCyHMxsQZuSydyNmS0Pxo= -cloud.google.com/go/gkebackup v1.3.0/go.mod h1:vUDOu++N0U5qs4IhG1pcOnD1Mac79xWy6GoBFlWCWBU= -cloud.google.com/go/gkeconnect v0.8.1 h1:a1ckRvVznnuvDWESM2zZDzSVFvggeBaVY5+BVB8tbT0= -cloud.google.com/go/gkeconnect v0.8.1/go.mod h1:KWiK1g9sDLZqhxB2xEuPV8V9NYzrqTUmQR9shJHpOZw= -cloud.google.com/go/gkehub v0.14.1 h1:2BLSb8i+Co1P05IYCKATXy5yaaIw/ZqGvVSBTLdzCQo= -cloud.google.com/go/gkehub v0.14.1/go.mod h1:VEXKIJZ2avzrbd7u+zeMtW00Y8ddk/4V9511C9CQGTY= -cloud.google.com/go/gkemulticloud v1.0.0 h1:MluqhtPVZReoriP5+adGIw+ij/RIeRik8KApCW2WMTw= -cloud.google.com/go/gkemulticloud v1.0.0/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw= -cloud.google.com/go/gsuiteaddons v1.6.1 h1:mi9jxZpzVjLQibTS/XfPZvl+Jr6D5Bs8pGqUjllRb00= -cloud.google.com/go/gsuiteaddons v1.6.1/go.mod h1:CodrdOqRZcLp5WOwejHWYBjZvfY0kOphkAKpF/3qdZY= -cloud.google.com/go/iap v1.8.1 h1:X1tcp+EoJ/LGX6cUPt3W2D4H2Kbqq0pLAsldnsCjLlE= -cloud.google.com/go/iap v1.8.1/go.mod h1:sJCbeqg3mvWLqjZNsI6dfAtbbV1DL2Rl7e1mTyXYREQ= -cloud.google.com/go/ids v1.4.1 h1:khXYmSoDDhWGEVxHl4c4IgbwSRR+qE/L4hzP3vaU9Hc= -cloud.google.com/go/ids v1.4.1/go.mod h1:np41ed8YMU8zOgv53MMMoCntLTn2lF+SUzlM+O3u/jw= -cloud.google.com/go/iot v1.7.1 h1:yrH0OSmicD5bqGBoMlWG8UltzdLkYzNUwNVUVz7OT54= -cloud.google.com/go/iot v1.7.1/go.mod h1:46Mgw7ev1k9KqK1ao0ayW9h0lI+3hxeanz+L1zmbbbk= -cloud.google.com/go/kms v1.15.0 h1:xYl5WEaSekKYN5gGRyhjvZKM22GVBBCzegGNVPy+aIs= -cloud.google.com/go/kms v1.15.0/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM= -cloud.google.com/go/language v1.10.1 h1:3MXeGEv8AlX+O2LyV4pO4NGpodanc26AmXwOuipEym0= -cloud.google.com/go/language v1.10.1/go.mod h1:CPp94nsdVNiQEt1CNjF5WkTcisLiHPyIbMhvR8H2AW0= -cloud.google.com/go/lifesciences v0.9.1 h1:axkANGx1wiBXHiPcJZAE+TDjjYoJRIDzbHC/WYllCBU= -cloud.google.com/go/lifesciences v0.9.1/go.mod h1:hACAOd1fFbCGLr/+weUKRAJas82Y4vrL3O5326N//Wc= -cloud.google.com/go/logging v1.7.0 h1:CJYxlNNNNAMkHp9em/YEXcfJg+rPDg7YfwoRpMU+t5I= -cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= -cloud.google.com/go/managedidentities v1.6.1 h1:2/qZuOeLgUHorSdxSQGtnOu9xQkBn37+j+oZQv/KHJY= -cloud.google.com/go/managedidentities v1.6.1/go.mod h1:h/irGhTN2SkZ64F43tfGPMbHnypMbu4RB3yl8YcuEak= -cloud.google.com/go/maps v1.4.0 h1:PdfgpBLhAoSzZrQXP+/zBc78fIPLZSJp5y8+qSMn2UU= -cloud.google.com/go/maps v1.4.0/go.mod h1:6mWTUv+WhnOwAgjVsSW2QPPECmW+s3PcRyOa9vgG/5s= -cloud.google.com/go/mediatranslation v0.8.1 h1:50cF7c1l3BanfKrpnTCaTvhf+Fo6kdF21DG0byG7gYU= -cloud.google.com/go/mediatranslation v0.8.1/go.mod h1:L/7hBdEYbYHQJhX2sldtTO5SZZ1C1vkapubj0T2aGig= -cloud.google.com/go/memcache v1.10.1 h1:7lkLsF0QF+Mre0O/NvkD9Q5utUNwtzvIYjrOLOs0HO0= -cloud.google.com/go/memcache v1.10.1/go.mod h1:47YRQIarv4I3QS5+hoETgKO40InqzLP6kpNLvyXuyaA= -cloud.google.com/go/metastore v1.12.0 h1:+9DsxUOHvsqvC0ylrRc/JwzbXJaaBpfIK3tX0Lx8Tcc= -cloud.google.com/go/metastore v1.12.0/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA= -cloud.google.com/go/monitoring v1.15.1 h1:65JhLMd+JiYnXr6j5Z63dUYCuOg770p8a/VC+gil/58= -cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM= -cloud.google.com/go/networkconnectivity v1.12.1 h1:LnrYM6lBEeTq+9f2lR4DjBhv31EROSAQi/P5W4Q0AEc= -cloud.google.com/go/networkconnectivity v1.12.1/go.mod h1:PelxSWYM7Sh9/guf8CFhi6vIqf19Ir/sbfZRUwXh92E= -cloud.google.com/go/networkmanagement v1.8.0 h1:/3xP37eMxnyvkfLrsm1nv1b2FbMMSAEAOlECTvoeCq4= -cloud.google.com/go/networkmanagement v1.8.0/go.mod h1:Ho/BUGmtyEqrttTgWEe7m+8vDdK74ibQc+Be0q7Fof0= -cloud.google.com/go/networksecurity v0.9.1 h1:TBLEkMp3AE+6IV/wbIGRNTxnqLXHCTEQWoxRVC18TzY= -cloud.google.com/go/networksecurity v0.9.1/go.mod h1:MCMdxOKQ30wsBI1eI659f9kEp4wuuAueoC9AJKSPWZQ= -cloud.google.com/go/notebooks v1.9.1 h1:CUqMNEtv4EHFnbogV+yGHQH5iAQLmijOx191innpOcs= -cloud.google.com/go/notebooks v1.9.1/go.mod h1:zqG9/gk05JrzgBt4ghLzEepPHNwE5jgPcHZRKhlC1A8= -cloud.google.com/go/optimization v1.4.1 h1:pEwOAmO00mxdbesCRSsfj8Sd4rKY9kBrYW7Vd3Pq7cA= -cloud.google.com/go/optimization v1.4.1/go.mod h1:j64vZQP7h9bO49m2rVaTVoNM0vEBEN5eKPUPbZyXOrk= -cloud.google.com/go/orchestration v1.8.1 h1:KmN18kE/xa1n91cM5jhCh7s1/UfIguSCisw7nTMUzgE= -cloud.google.com/go/orchestration v1.8.1/go.mod h1:4sluRF3wgbYVRqz7zJ1/EUNc90TTprliq9477fGobD8= -cloud.google.com/go/orgpolicy v1.11.1 h1:I/7dHICQkNwym9erHqmlb50LRU588NPCvkfIY0Bx9jI= -cloud.google.com/go/orgpolicy v1.11.1/go.mod h1:8+E3jQcpZJQliP+zaFfayC2Pg5bmhuLK755wKhIIUCE= -cloud.google.com/go/osconfig v1.12.1 h1:dgyEHdfqML6cUW6/MkihNdTVc0INQst0qSE8Ou1ub9c= -cloud.google.com/go/osconfig v1.12.1/go.mod h1:4CjBxND0gswz2gfYRCUoUzCm9zCABp91EeTtWXyz0tE= -cloud.google.com/go/oslogin v1.10.1 h1:LdSuG3xBYu2Sgr3jTUULL1XCl5QBx6xwzGqzoDUw1j0= -cloud.google.com/go/oslogin v1.10.1/go.mod h1:x692z7yAue5nE7CsSnoG0aaMbNoRJRXO4sn73R+ZqAs= -cloud.google.com/go/phishingprotection v0.8.1 h1:aK/lNmSd1vtbft/vLe2g7edXK72sIQbqr2QyrZN/iME= -cloud.google.com/go/phishingprotection v0.8.1/go.mod h1:AxonW7GovcA8qdEk13NfHq9hNx5KPtfxXNeUxTDxB6I= -cloud.google.com/go/policytroubleshooter v1.8.0 h1:XTMHy31yFmXgQg57CB3w9YQX8US7irxDX0Fl0VwlZyY= -cloud.google.com/go/policytroubleshooter v1.8.0/go.mod h1:tmn5Ir5EToWe384EuboTcVQT7nTag2+DuH3uHmKd1HU= -cloud.google.com/go/privatecatalog v0.9.1 h1:B/18xGo+E0EMS9LOEQ0zXz7F2asMgmVgTYGSI89MHOA= -cloud.google.com/go/privatecatalog v0.9.1/go.mod h1:0XlDXW2unJXdf9zFz968Hp35gl/bhF4twwpXZAW50JA= -cloud.google.com/go/pubsub v1.33.0 h1:6SPCPvWav64tj0sVX/+npCBKhUi/UjJehy9op/V3p2g= -cloud.google.com/go/pubsub v1.33.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc= -cloud.google.com/go/pubsublite v1.8.1 h1:pX+idpWMIH30/K7c0epN6V703xpIcMXWRjKJsz0tYGY= -cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0= -cloud.google.com/go/recaptchaenterprise/v2 v2.7.2 h1:IGkbudobsTXAwmkEYOzPCQPApUCsN4Gbq3ndGVhHQpI= -cloud.google.com/go/recaptchaenterprise/v2 v2.7.2/go.mod h1:kR0KjsJS7Jt1YSyWFkseQ756D45kaYNTlDPPaRAvDBU= -cloud.google.com/go/recommendationengine v0.8.1 h1:nMr1OEVHuDambRn+/y4RmNAmnR/pXCuHtH0Y4tCgGRQ= -cloud.google.com/go/recommendationengine v0.8.1/go.mod h1:MrZihWwtFYWDzE6Hz5nKcNz3gLizXVIDI/o3G1DLcrE= -cloud.google.com/go/recommender v1.10.1 h1:UKp94UH5/Lv2WXSQe9+FttqV07x/2p1hFTMMYVFtilg= -cloud.google.com/go/recommender v1.10.1/go.mod h1:XFvrE4Suqn5Cq0Lf+mCP6oBHD/yRMA8XxP5sb7Q7gpA= -cloud.google.com/go/redis v1.13.1 h1:YrjQnCC7ydk+k30op7DSjSHw1yAYhqYXFcOq1bSXRYA= -cloud.google.com/go/redis v1.13.1/go.mod h1:VP7DGLpE91M6bcsDdMuyCm2hIpB6Vp2hI090Mfd1tcg= -cloud.google.com/go/resourcemanager v1.9.1 h1:QIAMfndPOHR6yTmMUB0ZN+HSeRmPjR/21Smq5/xwghI= -cloud.google.com/go/resourcemanager v1.9.1/go.mod h1:dVCuosgrh1tINZ/RwBufr8lULmWGOkPS8gL5gqyjdT8= -cloud.google.com/go/resourcesettings v1.6.1 h1:Fdyq418U69LhvNPFdlEO29w+DRRjwDA4/pFamm4ksAg= -cloud.google.com/go/resourcesettings v1.6.1/go.mod h1:M7mk9PIZrC5Fgsu1kZJci6mpgN8o0IUzVx3eJU3y4Jw= -cloud.google.com/go/retail v1.14.1 h1:gYBrb9u/Hc5s5lUTFXX1Vsbc/9BEvgtioY6ZKaK0DK8= -cloud.google.com/go/retail v1.14.1/go.mod h1:y3Wv3Vr2k54dLNIrCzenyKG8g8dhvhncT2NcNjb/6gE= -cloud.google.com/go/run v1.2.0 h1:kHeIG8q+N6Zv0nDkBjSOYfK2eWqa5FnaiDPH/7/HirE= -cloud.google.com/go/run v1.2.0/go.mod h1:36V1IlDzQ0XxbQjUx6IYbw8H3TJnWvhii963WW3B/bo= -cloud.google.com/go/scheduler v1.10.1 h1:yoZbZR8880KgPGLmACOMCiY2tPk+iX4V/dkxqTirlz8= -cloud.google.com/go/scheduler v1.10.1/go.mod h1:R63Ldltd47Bs4gnhQkmNDse5w8gBRrhObZ54PxgR2Oo= -cloud.google.com/go/secretmanager v1.11.1 h1:cLTCwAjFh9fKvU6F13Y4L9vPcx9yiWPyWXE4+zkuEQs= -cloud.google.com/go/secretmanager v1.11.1/go.mod h1:znq9JlXgTNdBeQk9TBW/FnR/W4uChEKGeqQWAJ8SXFw= -cloud.google.com/go/security v1.15.1 h1:jR3itwycg/TgGA0uIgTItcVhA55hKWiNJxaNNpQJaZE= -cloud.google.com/go/security v1.15.1/go.mod h1:MvTnnbsWnehoizHi09zoiZob0iCHVcL4AUBj76h9fXA= -cloud.google.com/go/securitycenter v1.23.0 h1:XOGJ9OpnDtqg8izd7gYk/XUhj8ytjIalyjjsR6oyG0M= -cloud.google.com/go/securitycenter v1.23.0/go.mod h1:8pwQ4n+Y9WCWM278R8W3nF65QtY172h4S8aXyI9/hsQ= -cloud.google.com/go/servicedirectory v1.11.0 h1:pBWpjCFVGWkzVTkqN3TBBIqNSoSHY86/6RL0soSQ4z8= -cloud.google.com/go/servicedirectory v1.11.0/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ= -cloud.google.com/go/shell v1.7.1 h1:aHbwH9LSqs4r2rbay9f6fKEls61TAjT63jSyglsw7sI= -cloud.google.com/go/shell v1.7.1/go.mod h1:u1RaM+huXFaTojTbW4g9P5emOrrmLE69KrxqQahKn4g= -cloud.google.com/go/spanner v1.47.0 h1:aqiMP8dhsEXgn9K5EZBWxPG7dxIiyM2VaikqeU4iteg= -cloud.google.com/go/spanner v1.47.0/go.mod h1:IXsJwVW2j4UKs0eYDqodab6HgGuA1bViSqW4uH9lfUI= -cloud.google.com/go/speech v1.19.0 h1:MCagaq8ObV2tr1kZJcJYgXYbIn8Ai5rp42tyGYw9rls= -cloud.google.com/go/speech v1.19.0/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo= -cloud.google.com/go/storagetransfer v1.10.0 h1:+ZLkeXx0K0Pk5XdDmG0MnUVqIR18lllsihU/yq39I8Q= -cloud.google.com/go/storagetransfer v1.10.0/go.mod h1:DM4sTlSmGiNczmV6iZyceIh2dbs+7z2Ayg6YAiQlYfA= -cloud.google.com/go/talent v1.6.2 h1:j46ZgD6N2YdpFPux9mc7OAf4YK3tiBCsbLKc8rQx+bU= -cloud.google.com/go/talent v1.6.2/go.mod h1:CbGvmKCG61mkdjcqTcLOkb2ZN1SrQI8MDyma2l7VD24= -cloud.google.com/go/texttospeech v1.7.1 h1:S/pR/GZT9p15R7Y2dk2OXD/3AufTct/NSxT4a7nxByw= -cloud.google.com/go/texttospeech v1.7.1/go.mod h1:m7QfG5IXxeneGqTapXNxv2ItxP/FS0hCZBwXYqucgSk= -cloud.google.com/go/tpu v1.6.1 h1:kQf1jgPY04UJBYYjNUO+3GrZtIb57MfGAW2bwgLbR3A= -cloud.google.com/go/tpu v1.6.1/go.mod h1:sOdcHVIgDEEOKuqUoi6Fq53MKHJAtOwtz0GuKsWSH3E= -cloud.google.com/go/trace v1.10.1 h1:EwGdOLCNfYOOPtgqo+D2sDLZmRCEO1AagRTJCU6ztdg= -cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk= -cloud.google.com/go/translate v1.8.2 h1:PQHamiOzlehqLBJMnM72lXk/OsMQewZB12BKJ8zXrU0= -cloud.google.com/go/translate v1.8.2/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs= -cloud.google.com/go/video v1.19.0 h1:BRyyS+wU+Do6VOXnb8WfPr42ZXti9hzmLKLUCkggeK4= -cloud.google.com/go/video v1.19.0/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU= -cloud.google.com/go/videointelligence v1.11.1 h1:MBMWnkQ78GQnRz5lfdTAbBq/8QMCF3wahgtHh3s/J+k= -cloud.google.com/go/videointelligence v1.11.1/go.mod h1:76xn/8InyQHarjTWsBR058SmlPCwQjgcvoW0aZykOvo= -cloud.google.com/go/vision/v2 v2.7.2 h1:ccK6/YgPfGHR/CyESz1mvIbsht5Y2xRsWCPqmTNydEw= -cloud.google.com/go/vision/v2 v2.7.2/go.mod h1:jKa8oSYBWhYiXarHPvP4USxYANYUEdEsQrloLjrSwJU= -cloud.google.com/go/vmmigration v1.7.1 h1:gnjIclgqbEMc+cF5IJuPxp53wjBIlqZ8h9hE8Rkwp7A= -cloud.google.com/go/vmmigration v1.7.1/go.mod h1:WD+5z7a/IpZ5bKK//YmT9E047AD+rjycCAvyMxGJbro= -cloud.google.com/go/vmwareengine v1.0.0 h1:qsJ0CPlOQu/3MFBGklu752v3AkD+Pdu091UmXJ+EjTA= -cloud.google.com/go/vmwareengine v1.0.0/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0= -cloud.google.com/go/vpcaccess v1.7.1 h1:ram0GzjNWElmbxXMIzeOZUkQ9J8ZAahD6V8ilPGqX0Y= -cloud.google.com/go/vpcaccess v1.7.1/go.mod h1:FogoD46/ZU+JUBX9D606X21EnxiszYi2tArQwLY4SXs= -cloud.google.com/go/webrisk v1.9.1 h1:Ssy3MkOMOnyRV5H2bkMQ13Umv7CwB/kugo3qkAX83Fk= -cloud.google.com/go/webrisk v1.9.1/go.mod h1:4GCmXKcOa2BZcZPn6DCEvE7HypmEJcJkr4mtM+sqYPc= -cloud.google.com/go/websecurityscanner v1.6.1 h1:CfEF/vZ+xXyAR3zC9iaC/QRdf1MEgS20r5UR17Q4gOg= -cloud.google.com/go/websecurityscanner v1.6.1/go.mod h1:Njgaw3rttgRHXzwCB8kgCYqv5/rGpFCsBOvPbYgszpg= -cloud.google.com/go/workflows v1.11.1 h1:2akeQ/PgtRhrNuD/n1WvJd5zb7YyuDZrlOanBj2ihPg= -cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= -github.com/OpenIMSDK/protocol v0.0.14 h1:cvQ3f8MTcyYygAnZ7Exq6zIbvHGCEV0fWdpzjQEDDBQ= -github.com/OpenIMSDK/protocol v0.0.14/go.mod h1:F25dFrwrIx3lkNoiuf6FkCfxuwf8L4Z8UIsdTHP/r0Y= -github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409 h1:DTQ/38ao/CfXsrK0cSAL+h4R/u0VVvfWLZEOlLwEROI= -github.com/alecthomas/kingpin/v2 v2.3.1 h1:ANLJcKmQm4nIaog7xdr/id6FM6zm5hHnfZrvtKPxqGg= -github.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= -github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= -github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= -github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= -github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe h1:QQ3GSy+MqSHxm/d8nCtnAiZdYFd45cYZPs8vOOIYKfk= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= -github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= -github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f h1:7T++XKzy4xg7PKy+bM+Sa9/oe1OC88yz2hXQUISoXfA= -github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= -github.com/envoyproxy/protoc-gen-validate v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= -github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= -github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= -github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8= -github.com/google/go-pkcs11 v0.2.0 h1:5meDPB26aJ98f+K9G21f0AqZwo/S5BJMJh8nuhMbdsI= -github.com/google/go-pkcs11 v0.2.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= -github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= -github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= -github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= -github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI= -github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= -github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY= -github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/onsi/ginkgo/v2 v2.0.0 h1:CcuG/HvWNkkaqCUpJifQY8z7qEMBJya6aLPx6ftGyjQ= -github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563 h1:2VDxTtn9dAqI2DnnvB9fXpPE4DblOmquyzmN2zxTD8A= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563 h1:FoX+MK4vHThvPO6FbP5q98zD8S3n+d5+DbtK7skl++c= -github.com/xdg/scram v1.0.3 h1:nTadYh2Fs4BK2xdldEa2g5bbaZp0/+1nJMMPtPxS/to= -github.com/xdg/stringprep v1.0.3 h1:cmL5Enob4W83ti/ZHuZLuKD/xqJfus4fVPwE+/BDm+4= -github.com/xhit/go-str2duration v1.2.0 h1:BcV5u025cITWxEQKGWr1URRzrcXtu7uk8+luz3Yuhwc= -github.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4= -github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= -go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0= -golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= -golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577 h1:ZX0eQu2J+jOO87sq8fQG8J/Nfp7D7BhHpixIE5EYK/k= -google.golang.org/genproto/googleapis/bytestream v0.0.0-20230807174057-1744710a1577/go.mod h1:NjCQG/D8JandXxM57PZbAJL1DCNL6EypA0vPPwfsc7c= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs= -rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= diff --git a/install_guide.sh b/install_guide.sh index a32bd24f4..c6532feb8 100755 --- a/install_guide.sh +++ b/install_guide.sh @@ -152,7 +152,7 @@ EOF cd ..; docker-compose up -d; cd scripts; - ./docker_check_service.sh; + ./docker-check-service.sh; } read choice diff --git a/internal/api/user.go b/internal/api/user.go index 59d293231..bfa1d0df7 100644 --- a/internal/api/user.go +++ b/internal/api/user.go @@ -88,7 +88,6 @@ func (u *UserApi) GetUsersOnlineStatus(c *gin.Context) { log.ZWarn(c, "GetUsersOnlineStatus rpc err", err) parseError := apiresp.ParseError(err) - log.ZDebug(c, "errcode bantanger", "errcode", parseError.ErrCode) if parseError.ErrCode == errs.NoPermissionError { apiresp.GinError(c, err) return diff --git a/internal/tools/msg_doc_convert.go b/internal/tools/msg_doc_convert.go index 598d0dbcf..75ae36eda 100644 --- a/internal/tools/msg_doc_convert.go +++ b/internal/tools/msg_doc_convert.go @@ -1,3 +1,17 @@ +// 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 ( diff --git a/openim-chat/config/config.yaml b/openim-chat/config/config.yaml deleted file mode 100644 index 20351b344..000000000 --- a/openim-chat/config/config.yaml +++ /dev/null @@ -1,104 +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. - -# 需要先启动OpenIMServer -zookeeper: - schema: openim - zkAddr: - - 127.0.0.1:2181 - username: "" - password: "" - -chatApi: - openImChatApiPort: [ 10008 ] - listenIP: - -adminApi: - openImAdminApiPort: [ 10009 ] - listenIP: - -rpc: - registerIP: #作为rpc启动时,注册到zookeeper的IP,api/gateway能访问到此ip和对应的rpcPort中的端口 - listenIP: #默认为0.0.0.0 - -rpcPort: - openImAdminPort: [ 30200 ] - openImChatPort: [ 30300 ] -rpcRegisterName: - openImAdminName: admin - openImChatName: chat - -# 没有配置表示和OpenIM一致 -mysql: - # address: [ 127.0.0.1:13306 ] #目前仅支持单机 - # username: root #用户名 - # password: openIM123 #密码 - # database: openIM_v2 #不建议修改 - # maxOpenConn: 1000 #最大连接数 - # maxIdleConn: 100 #最大空闲连接数 - # maxLifeTime: 60 #连接可以重复使用的最长时间(秒) - # logLevel: 4 #日志级别 1=slient 2=error 3=warn 4=info - # slowThreshold: 500 #慢语句阈值 (毫秒) - database: openim_enterprise - -# 没有配置表示和OpenIM一致 -log: - storageLocation: ../logs/ #存放目录 -# rotationTime: 24 #日志旋转时间 -# remainRotationCount: 2 #日志数量 -# remainLogLevel: 6 #日志级别 6表示全都打印, -# isStdout: false -# isJson: false -# withStack: false - -# secret: openIM123 -#tokenPolicy: -# expire: 86400 - -verifyCode: - validTime: 300 # 验证码有效时间 - validCount: 5 # 验证码有效次数 - uintTime: 86400 # 单位时间间隔 - maxCount: 10 # 单位时间内最大获取次数 - superCode: "666666" # 超级验证码(只有use为空时使用) - len: 6 # 验证码长度 - use: "" # 使用的验证码服务(use: "ali") - ali: - endpoint: "dysmsapi.aliyuncs.com" - accessKeyId: "" - accessKeySecret: "" - signName: "" - verificationCodeTemplateCode: "" - -# 获取ip的header,没有配置直接获取远程地址 -#proxyHeader: "X-Forwarded-For" - -adminList: - - adminID: admin1 - nickname: chat1 - imAdmin: openIM123456 - - adminID: admin2 - nickname: chat2 - imAdmin: openIM654321 - - adminID: admin3 - nickname: chat3 - imAdmin: openIMAdmin - - -openIMUrl: "http://127.0.0.1:10002" - -redis: - address: [ 127.0.0.1:16379 ] - username: - password: openIM123 \ No newline at end of file diff --git a/openim-chat/scripts/admin_rpc_start.sh b/openim-chat/scripts/admin_rpc_start.sh deleted file mode 100644 index f6a638228..000000000 --- a/openim-chat/scripts/admin_rpc_start.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env bash - - -# 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. - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${SCRIPTS_ROOT}")/.. - -source $OPENIM_ROOT/scripts/style_info.sh -source $OPENIM_ROOT/scripts/path_info.sh -source $OPENIM_ROOT/scripts/function.sh - -list1=$(cat $config_path | grep openImPushPort | awk -F '[:]' '{print $NF}') -list2=$(cat $config_path | grep pushPrometheusPort | awk -F '[:]' '{print $NF}') -list_to_string $list1 -rpc_ports=($ports_array) -list_to_string $list2 -prome_ports=($ports_array) - -#Check if the service exists -#If it is exists,kill this process -check=$(ps | grep -w ./${push_name} | grep -v grep | wc -l) -if [ $check -ge 1 ]; then - oldPid=$(ps | grep -w ./${push_name} | grep -v grep | awk '{print $2}') - kill -9 $oldPid -fi -#Waiting port recycling -sleep 1 -cd ${push_binary_root} - -for ((i = 0; i < ${#rpc_ports[@]}; i++)); do - nohup ./${push_name} -port ${rpc_ports[$i]} -prometheus_port ${prome_ports[$i]} >>../logs/openIM.log 2>&1 & -done - -sleep 3 -#Check launched service process -check=$(ps | grep -w ./${push_name} | grep -v grep | wc -l) -if [ $check -ge 1 ]; then - newPid=$(ps | grep -w ./${push_name} | grep -v grep | awk '{print $2}') - ports=$(netstat -netulp | grep -w ${newPid} | awk '{print $4}' | awk -F '[:]' '{print $NF}') - allPorts="" - - for i in $ports; do - allPorts=${allPorts}"$i " - done - echo -e ${SKY_BLUE_PREFIX}"SERVICE START SUCCESS "${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"SERVICE_NAME: "${COLOR_SUFFIX}${YELLOW_PREFIX}${push_name}${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${YELLOW_PREFIX}${newPid}${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${YELLOW_PREFIX}${allPorts}${COLOR_SUFFIX} -else - echo -e ${YELLOW_PREFIX}${push_name}${COLOR_SUFFIX}${RED_PREFIX}"SERVICE START ERROR, PLEASE CHECK openIM.log"${COLOR_SUFFIX} -fi diff --git a/openim-chat/scripts/build.cmd b/openim-chat/scripts/build.cmd deleted file mode 100644 index f100073bc..000000000 --- a/openim-chat/scripts/build.cmd +++ /dev/null @@ -1,14 +0,0 @@ -@echo off - -set "api_apps=admin-api chat-api" -set "rpc_apps=admin-rpc chat-rpc" - -for %%a in (%api_apps%) do ( - go build -o %%a.exe ../cmd/api/%%a/main.go -) - -for %%a in (%rpc_apps%) do ( - go build -o %%a.exe ../cmd/rpc/%%a/main.go -) - -move *exe ../cmd diff --git a/openim-chat/scripts/build_all_service.sh b/openim-chat/scripts/build_all_service.sh deleted file mode 100644 index a424ac7b1..000000000 --- a/openim-chat/scripts/build_all_service.sh +++ /dev/null @@ -1,134 +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 -set -o pipefail - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}" - -echo -e "" - -echo -e "${BACKGROUND_BLUE}===============> Building all using make build binary files ${COLOR_SUFFIX}" - -echo -e "" -echo -e "${BOLD_PREFIX}____________________________________________________________ ${COLOR_SUFFIX}" - - -bin_dir="$BIN_DIR" -logs_dir="$OPENIM_ROOT/logs" - -echo "==> bin_dir=$bin_dir" -echo "==> logs_dir=$logs_dir" - - -cd $SCRIPTS_ROOT/.. - -# CPU core number -cpu_count=$(lscpu | grep -e '^CPU(s):' | awk '{print $2}') -echo -e "${GREEN_PREFIX}======> cpu_count=$cpu_count${COLOR_SUFFIX}" - -# Count the number of concurrent compilations (half the number of cpus) -compile_count=$((cpu_count / 2)) - -# Execute 'make build' run the make command for concurrent compilation -make -j$compile_count build - -if [ $? -ne 0 ]; then - echo "make build Error, script exits" - exit 1 -fi - -# Get the current operating system and architecture -OS=$(uname -s | tr '[:upper:]' '[:lower:]') -ARCH=$(uname -m) - -# Select the repository home directory based on the operating system and architecture -if [[ "$OS" == "darwin" ]]; then - if [[ "$ARCH" == "x86_64" ]]; then - REPO_DIR="darwin/amd64" - else - REPO_DIR="darwin/386" - fi -elif [[ "$OS" == "linux" ]]; then - if [[ "$ARCH" == "x86_64" ]]; then - REPO_DIR="linux/amd64" - elif [[ "$ARCH" == "arm64" ]]; then - REPO_DIR="linux/arm64" - elif [[ "$ARCH" == "mips64" ]]; then - REPO_DIR="linux/mips64" - elif [[ "$ARCH" == "mips64le" ]]; then - REPO_DIR="linux/mips64le" - elif [[ "$ARCH" == "ppc64le" ]]; then - REPO_DIR="linux/ppc64le" - elif [[ "$ARCH" == "s390x" ]]; then - REPO_DIR="linux/s390x" - else - REPO_DIR="linux/386" - fi -elif [[ "$OS" == "windows" ]]; then - if [[ "$ARCH" == "x86_64" ]]; then - REPO_DIR="windows/amd64" - else - REPO_DIR="windows/386" - fi -else - echo -e "${RED_PREFIX}Unsupported OS: $OS${COLOR_SUFFIX}" - exit 1 -fi - -# Determine if all scripts were successfully built -BUILD_SUCCESS=true -FAILED_SCRIPTS=() - -for binary in $(find _output/bin/platforms/$REPO_DIR -type f); do - if [[ ! -x $binary ]]; then - FAILED_SCRIPTS+=("$binary") - BUILD_SUCCESS=false - fi -done - -echo -e " " - -echo -e "${BOLD_PREFIX}=====================> Build Results <=====================${COLOR_SUFFIX}" - -echo -e " " - -if [[ "$BUILD_SUCCESS" == true ]]; then - echo -e "${GREEN_PREFIX}All binaries built successfully.${COLOR_SUFFIX}" -else - echo -e "${RED_PREFIX}Some binary builds failed. Please check the following binary files:${COLOR_SUFFIX}" - for script in "${FAILED_SCRIPTS[@]}"; do - echo -e "${RED_PREFIX}$script${COLOR_SUFFIX}" - done -fi - -echo -e " " - -echo -e "${BOLD_PREFIX}============================================================${COLOR_SUFFIX}" - -echo -e " " diff --git a/openim-chat/scripts/check_all.sh b/openim-chat/scripts/check_all.sh deleted file mode 100644 index 7e3f9d616..000000000 --- a/openim-chat/scripts/check_all.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env bash - - -# 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. - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${SCRIPTS_ROOT}")/.. - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -service_port_name=( - openImChatApiPort - openImAdminApiPort - #api port name - openImAdminPort - openImChatPort -) - -switch=$(cat $config_path | grep demoswitch |awk -F '[:]' '{print $NF}') -for i in ${service_port_name[*]}; do - list=$(cat $config_path | grep -w ${i} | awk -F '[:]' '{print $NF}') - list_to_string $list - for j in ${ports_array}; do - port=$(ss -tunlp| grep -E 'api|rpc|open_im' | awk '{print $5}' | grep -w ${j} | awk -F '[:]' '{print $NF}') - if [[ ${port} -ne ${j} ]]; then - echo -e ${YELLOW_PREFIX}${i}${COLOR_SUFFIX}${RED_PREFIX}" service does not start normally,not initiated port is "${COLOR_SUFFIX}${YELLOW_PREFIX}${j}${COLOR_SUFFIX} - echo -e ${RED_PREFIX}"please check ../logs/openIM.log "${COLOR_SUFFIX} - exit -1 - else - echo -e ${j}${GREEN_PREFIX}" port has been listening,belongs service is "${i}${COLOR_SUFFIX} - fi - done -done \ No newline at end of file diff --git a/openim-chat/scripts/docker_start_all.sh b/openim-chat/scripts/docker_start_all.sh deleted file mode 100644 index 21b2c6f87..000000000 --- a/openim-chat/scripts/docker_start_all.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env bash - -# 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. - -#!/usr/bin/env bash - - -# Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -source "$SCRIPTS_ROOT/style_info.sh" -source "$SCRIPTS_ROOT/path_info.sh" -source "$SCRIPTS_ROOT/function.sh" - -printf "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=%s${COLOR_SUFFIX}\n" "$SCRIPTS_ROOT" -printf "${YELLOW_PREFIX}=======>OPENIM_ROOT=%s${COLOR_SUFFIX}\n" "$OPENIM_ROOT" -printf "${YELLOW_PREFIX}=======>pwd=%s${COLOR_SUFFIX}\n" "$PWD" - -bin_dir="$BIN_DIR" -logs_dir="$SCRIPTS_ROOT/../logs" - -printf "${YELLOW_PREFIX}=======>bin_dir=%s${COLOR_SUFFIX}\n" "$bin_dir" -printf "${YELLOW_PREFIX}=======>logs_dir=%s${COLOR_SUFFIX}\n" "$logs_dir" -printf "${YELLOW_PREFIX}=======>sdk_db_dir=%s${COLOR_SUFFIX}\n" "$sdk_db_dir" - -# Service filenames -service_filenames=( - chat-api - admin-api - #rpc - admin-rpc - chat-rpc -) - -# Service config port names -service_port_names=( - openImChatApiPort - openImAdminApiPort - #api port name - openImAdminPort - openImChatPort -) - -service_prometheus_port_names=() - -cd "$SCRIPTS_ROOT" - -# Function to kill a service -kill_service() { - local service_name=$1 - local pid=$(pgrep -f "$service_name") - if [ -n "$pid" ]; then - echo "$service_name service has been started, pid: $pid" - echo "Killing the service $service_name, pid: $pid" - killall "$service_name" - sleep 0.5 - fi -} - -for ((i = 0; i < ${#service_filenames[*]}; i++)); do - service_name="${service_filenames[$i]}" - kill_service "$service_name" - cd "$SCRIPTS_ROOT" - - # Get the rpc ports from the configuration file - readarray -t portList < "$config_path" - service_ports=() - for line in "${portList[@]}"; do - if [[ $line == *"${service_port_names[$i]}"* ]]; then - port=$(echo "$line" | awk -F ':' '{print $NF}') - service_ports+=("$port") - fi - done - - # Start related rpc services based on the number of ports - for port in "${service_ports[@]}"; do - # Start the service in the background - cmd="$bin_dir/$service_name -port $port --config_folder_path $config_path" - if [[ $i -eq 0 || $i -eq 1 ]]; then - cmd="$bin_dir/$service_name -port $port --config_folder_path $config_path" - fi - echo "$cmd" - nohup "$cmd" >> "${logs_dir}/openIM.log" 2>&1 & - sleep 1 - done -done - -sleep infinity diff --git a/openim-chat/scripts/githooks/commit-msg b/openim-chat/scripts/githooks/commit-msg deleted file mode 100644 index c7b130cd8..000000000 --- a/openim-chat/scripts/githooks/commit-msg +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env bash - -# Copyright © 2023 OpenIMSDK. -# -# 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. -# -# ============================================================================== -# -# Store this file as .git/hooks/commit-msg in your repository in order to -# enforce checking for proper commit message format before actual commits. -# You may need to make the scripts executable by 'chmod +x .git/hooks/commit-msg'. - -# commit-msg use go-gitlint tool, install go-gitlint via `go get github.com/llorllale/go-gitlint/cmd/go-gitlint` -# go-gitlint --msg-file="$1" - -# An example hook scripts to check the commit log message. -# Called by "git commit" with one argument, the name of the file -# that has the commit message. The hook should exit with non-zero -# status after issuing an appropriate message if it wants to stop the -# commit. The hook is allowed to edit the commit message file. - -YELLOW="\e[93m" -GREEN="\e[32m" -RED="\e[31m" -ENDCOLOR="\e[0m" - -printMessage() { - printf "${YELLOW}OpenIM : $1${ENDCOLOR}\n" -} - -printSuccess() { - printf "${GREEN}OpenIM : $1${ENDCOLOR}\n" -} - -printError() { - printf "${RED}OpenIM : $1${ENDCOLOR}\n" -} - -printMessage "Running the OpenIM commit-msg hook." - -# This example catches duplicate Signed-off-by lines. - -test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { - echo >&2 Duplicate Signed-off-by lines. - exit 1 -} - -# TODO: go-gitlint dir set -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/../.. -GITLINT_DIR="$OPENIM_ROOT/_output/tools/go-gitlint" - -$GITLINT_DIR \ - --msg-file=$1 \ - --subject-regex="^(build|chore|ci|docs|feat|feature|fix|perf|refactor|revert|style|bot|test)(.*)?:\s?.*" \ - --subject-maxlen=150 \ - --subject-minlen=10 \ - --body-regex=".*" \ - --max-parents=1 - -if [ $? -ne 0 ] -then - if ! command -v $GITLINT_DIR &>/dev/null; then - printError "$GITLINT_DIR not found. Please run 'make tools' OR 'make tools.verify.go-gitlint' make verto install it." - fi - printError "Please fix your commit message to match kubecub coding standards" - printError "https://gist.github.com/cubxxw/126b72104ac0b0ca484c9db09c3e5694#file-githook-md" - exit 1 -fi - -### Add Sign-off-by line to the end of the commit message -# Get local git config -NAME=$(git config user.name) -EMAIL=$(git config user.email) - -# Check if the commit message contains a sign-off line -grep -qs "^Signed-off-by: " "$1" -SIGNED_OFF_BY_EXISTS=$? - -# Add "Signed-off-by" line if it doesn't exist -if [ $SIGNED_OFF_BY_EXISTS -ne 0 ]; then - echo -e "\nSigned-off-by: $NAME <$EMAIL>" >> "$1" -fi \ No newline at end of file diff --git a/openim-chat/scripts/githooks/pre-commit b/openim-chat/scripts/githooks/pre-commit deleted file mode 100644 index 9c44ecb05..000000000 --- a/openim-chat/scripts/githooks/pre-commit +++ /dev/null @@ -1,112 +0,0 @@ -#!/usr/bin/env bash - -# Copyright © 2023 OpenIMSDK. -# -# 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 is a pre-commit hook that ensures attempts to commit files that are -# are larger than $limit to your _local_ repo fail, with a helpful error message. - -# You can override the default limit of 2MB by supplying the environment variable: -# GIT_FILE_SIZE_LIMIT=50000000 git commit -m "test: this commit is allowed file sizes up to 50MB" -# -# ============================================================================== -# - -LC_ALL=C - -local_branch="$(git rev-parse --abbrev-ref HEAD)" -valid_branch_regex="^(main|master|develop|release(-[a-zA-Z0-9._-]+)?)$|(feature|feat|openim|hotfix|test|bug|bot|ci|cicd|style|)\/[a-z0-9._-]+$|^HEAD$" - -YELLOW="\e[93m" -GREEN="\e[32m" -RED="\e[31m" -ENDCOLOR="\e[0m" - -printMessage() { - printf "${YELLOW}openim : $1${ENDCOLOR}\n" -} - -printSuccess() { - printf "${GREEN}openim : $1${ENDCOLOR}\n" -} - -printError() { - printf "${RED}openim : $1${ENDCOLOR}\n" -} - -printMessage "Running local openim pre-commit hook." - -# flutter format . -# https://gist.github.com/cubxxw/126b72104ac0b0ca484c9db09c3e5694#file-githook-md -# TODO! GIT_FILE_SIZE_LIMIT=50000000 git commit -m "test: this commit is allowed file sizes up to 50MB" -# Maximum file size limit in bytes -limit=${GIT_FILE_SIZE_LIMIT:-2000000} # Default 2MB -limitInMB=$(( $limit / 1000000 )) - -function file_too_large(){ - filename=$0 - filesize=$(( $1 / 2**20 )) - - cat < /dev/null 2>&1 -then - against=HEAD -else - against="$empty_tree" -fi - -# Set split so that for loop below can handle spaces in file names by splitting on line breaks -IFS=' -' - -shouldFail=false -for file in $( git diff-index --cached --name-only $against ); do - file_size=$(([ ! -f $file ] && echo 0) || (ls -la $file | awk '{ print $5 }')) - if [ "$file_size" -gt "$limit" ]; then - printError "File $file is $(( $file_size / 10**6 )) MB, which is larger than our configured limit of $limitInMB MB" - shouldFail=true - fi -done - -if $shouldFail -then - printMessage "If you really need to commit this file, you can override the size limit by setting the GIT_FILE_SIZE_LIMIT environment variable, e.g. GIT_FILE_SIZE_LIMIT=42000000 for 42MB. Or, commit with the --no-verify switch to skip the check entirely." - printError "Commit aborted" - exit 1; -fi - -if [[ ! $local_branch =~ $valid_branch_regex ]] -then - printError "There is something wrong with your branch name. Branch names in this project must adhere to this contract: $valid_branch_regex. -Your commit will be rejected. You should rename your branch to a valid name(feat/name OR bug/name) and try again." - printError "For more on this, read on: https://gist.github.com/cubxxw/126b72104ac0b0ca484c9db09c3e5694" - exit 1 -fi \ No newline at end of file diff --git a/openim-chat/scripts/githooks/pre-push b/openim-chat/scripts/githooks/pre-push deleted file mode 100644 index 297cadc73..000000000 --- a/openim-chat/scripts/githooks/pre-push +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env bash - -# Copyright © 2023 OpenIMSDK. -# -# 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. -# -# ============================================================================== -# - -YELLOW="\e[93m" -GREEN="\e[32m" -RED="\e[31m" -ENDCOLOR="\e[0m" - -local_branch="$(git rev-parse --abbrev-ref HEAD)" -valid_branch_regex="^(main|master|develop|release(-[a-zA-Z0-9._-]+)?)$|(feature|feat|openim|hotfix|test|bug|ci|cicd|style|)\/[a-z0-9._-]+$|^HEAD$" - -printMessage() { - printf "${YELLOW}OpenIM : $1${ENDCOLOR}\n" -} - -printSuccess() { - printf "${GREEN}OpenIM : $1${ENDCOLOR}\n" -} - -printError() { - printf "${RED}OpenIM : $1${ENDCOLOR}\n" -} - -printMessage "Running local OpenIM pre-push hook." - -if [[ `git status --porcelain` ]]; then - printError "This scripts needs to run against committed code only. Please commit or stash you changes." - exit 1 -fi - -COLOR_SUFFIX="\033[0m" - -BLACK_PREFIX="\033[30m" -RED_PREFIX="\033[31m" -GREEN_PREFIX="\033[32m" -BACKGROUND_GREEN="\033[33m" -BLUE_PREFIX="\033[34m" -PURPLE_PREFIX="\033[35m" -SKY_BLUE_PREFIX="\033[36m" -WHITE_PREFIX="\033[37m" -BOLD_PREFIX="\033[1m" -UNDERLINE_PREFIX="\033[4m" -ITALIC_PREFIX="\033[3m" - -# Function to print colored text -print_color() { - local text=$1 - local color=$2 - echo -e "${color}${text}${COLOR_SUFFIX}" -} - -# Function to print section separator -print_separator() { - print_color "==========================================================" ${PURPLE_PREFIX} -} - -# Get current time -time=$(date +"%Y-%m-%d %H:%M:%S") - -# Print section separator -print_separator - -# Print time of submission -print_color "PTIME: ${time}" "${BOLD_PREFIX}${CYAN_PREFIX}" -echo "" -author=$(git config user.name) -repository=$(basename -s .git $(git config --get remote.origin.url)) - -# Print additional information if needed -print_color "Repository: ${repository}" "${BLUE_PREFIX}" -echo "" - -print_color "Author: ${author}" "${PURPLE_PREFIX}" - -# Print section separator -print_separator - -file_list=$(git diff --name-status HEAD @{u}) -added_files=$(grep -c '^A' <<< "$file_list") -modified_files=$(grep -c '^M' <<< "$file_list") -deleted_files=$(grep -c '^D' <<< "$file_list") - -print_color "Added Files: ${added_files}" "${BACKGROUND_GREEN}" -print_color "Modified Files: ${modified_files}" "${BACKGROUND_GREEN}" -print_color "Deleted Files: ${deleted_files}" "${BACKGROUND_GREEN}" - -if [[ ! $local_branch =~ $valid_branch_regex ]] -then - printError "There is something wrong with your branch name. Branch names in this project must adhere to this contract: $valid_branch_regex. -Your commit will be rejected. You should rename your branch to a valid name(feat/name OR bug/name) and try again." - printError "For more on this, read on: https://gist.github.com/cubxxw/126b72104ac0b0ca484c9db09c3e5694" - exit 1 -fi - -# -#printMessage "Running the Flutter analyzer" -#flutter analyze -# -#if [ $? -ne 0 ]; then -# printError "Flutter analyzer error" -# exit 1 -#fi -# -#printMessage "Finished running the Flutter analyzer" diff --git a/openim-chat/scripts/path_info.sh b/openim-chat/scripts/path_info.sh deleted file mode 100644 index 5a8a0854d..000000000 --- a/openim-chat/scripts/path_info.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/usr/bin/env bash -# 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. - - - -#Don't put the space between "=" - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -# Determine the architecture and version -architecture=$(uname -m) -version=$(uname -s | tr '[:upper:]' '[:lower:]') - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh - -cd $SCRIPTS_ROOT - -# Define the supported architectures and corresponding bin directories -declare -A supported_architectures=( - ["linux-amd64"]="_output/bin/platforms/linux/amd64" - ["linux-arm64"]="_output/bin/platforms/linux/arm64" - ["linux-mips64"]="_output/bin/platforms/linux/mips64" - ["linux-mips64le"]="_output/bin/platforms/linux/mips64le" - ["linux-ppc64le"]="_output/bin/platforms/linux/ppc64le" - ["linux-s390x"]="_output/bin/platforms/linux/s390x" - ["darwin-amd64"]="_output/bin/platforms/darwin/amd64" - ["windows-amd64"]="_output/bin/platforms/windows/amd64" - ["linux-x86_64"]="_output/bin/platforms/linux/amd64" # Alias for linux-amd64 - ["darwin-x86_64"]="_output/bin/platforms/darwin/amd64" # Alias for darwin-amd64 -) - -# Check if the architecture and version are supported -if [[ -z ${supported_architectures["$version-$architecture"]} ]]; then - echo -e "${BLUE_PREFIX}================> Unsupported architecture: $architecture or version: $version${COLOR_SUFFIX}" - exit 1 -fi - -echo -e "${BLUE_PREFIX}================> Architecture: $architecture${COLOR_SUFFIX}" - -# Set the BIN_DIR based on the architecture and version -BIN_DIR=${SCRIPTS_ROOT}/../${supported_architectures["$version-$architecture"]} - -echo -e "${BLUE_PREFIX}================> BIN_DIR: $OPENIM_ROOT/$BIN_DIR${COLOR_SUFFIX}" - -#Global configuration file default dir -config_path="$OPENIM_ROOT/config/config.yaml" -configfile_path="$OPENIM_ROOT/config" -log_path="$OPENIM_ROOT/log" - -#servicefile dir path -service_source_root=( - #api service file - $OPENIM_ROOT/cmd/api/chat-api/ - $OPENIM_ROOT/cmd/api/admin-api/ - #rpc service file - $OPENIM_ROOT/cmd/rpc/admin-rpc/ - $OPENIM_ROOT/cmd/rpc/chat-rpc/ -) -#service filename -service_names=( - chat-api - admin-api - chat-rpc - admin-rpc -) diff --git a/openim-chat/scripts/start.bat b/openim-chat/scripts/start.bat deleted file mode 100644 index 2c765f10d..000000000 --- a/openim-chat/scripts/start.bat +++ /dev/null @@ -1,5 +0,0 @@ -cd /d %~dp0../cmd -start admin-rpc.exe -start chat-rpc.exe -start chat-api.exe -start admin-api.exe \ No newline at end of file diff --git a/openim-chat/scripts/start_all.sh b/openim-chat/scripts/start_all.sh deleted file mode 100644 index b2ee16214..000000000 --- a/openim-chat/scripts/start_all.sh +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env bash - -# 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. - -set -e -set -o pipefail - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${SCRIPTS_ROOT}")/.. - -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}" - -# if [ ! -d "${OPENIM_ROOT}/_output/bin/platforms" ]; then -# cd $OPENIM_ROOT -# # exec build_all_service.sh -# "${SCRIPTS_ROOT}/build_all_service.sh" -# fi - -bin_dir="$BIN_DIR" -logs_dir="$SCRIPTS_ROOT/../logs" - -echo -e "${YELLOW_PREFIX}=======>bin_dir=$bin_dir${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>logs_dir=$logs_dir${COLOR_SUFFIX}" - -#service filename -service_filename=( - chat-api - admin-api - #rpc - admin-rpc - chat-rpc -) - -#service config port name -service_port_name=( -openImChatApiPort -openImAdminApiPort - #api port name - openImAdminPort - openImChatPort -) - -service_prometheus_port_name=( - -) - -# Automatically created when there is no bin, logs folder -if [ ! -d $logs_dir ]; then - mkdir -p $logs_dir -fi -cd $SCRIPTS_ROOT - -for ((i = 0; i < ${#service_filename[*]}; i++)); do - #Check whether the service exists -# service_name="ps |grep -w ${service_filename[$i]} |grep -v grep" -# count="${service_name}| wc -l" -# -# if [ $(eval ${count}) -gt 0 ]; then -# pid="${service_name}| awk '{print \$2}'" -# echo "${service_filename[$i]} service has been started,pid:$(eval $pid)" -# echo "killing the service ${service_filename[$i]} pid:$(eval $pid)" -# #kill the service that existed -# kill -9 $(eval $pid) -# sleep 0.5 -# fi - cd $SCRIPTS_ROOT - - #Get the rpc port in the configuration file - portList=$(cat $config_path | grep ${service_port_name[$i]} | awk -F '[:]' '{print $NF}') - list_to_string ${portList} - service_ports=($ports_array) - - #Start related rpc services based on the number of ports - for ((j = 0; j < ${#service_ports[*]}; j++)); do - #Start the service in the background - cmd="$bin_dir/${service_filename[$i]} -port ${service_ports[$j]} --config_folder_path ${config_path}" - if [ $i -eq 0 -o $i -eq 1 ]; then - cmd="$bin_dir/${service_filename[$i]} -port ${service_ports[$j]} --config_folder_path ${config_path}" - fi - echo $cmd - nohup $cmd >>${logs_dir}/openIM.log 2>&1 & - sleep 1 -# pid="netstat -ntlp|grep $j |awk '{printf \$7}'|cut -d/ -f1" -# echo -e "${GREEN_PREFIX}${service_filename[$i]} start success,port number:${service_ports[$j]} pid:$(eval $pid)$COLOR_SUFFIX" - done -done \ No newline at end of file diff --git a/openim-chat/scripts/stop_all.sh b/openim-chat/scripts/stop_all.sh deleted file mode 100644 index 6e69ba53f..000000000 --- a/openim-chat/scripts/stop_all.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash - -# 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. - -#fixme This scripts is to stop the service -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(cd $(dirname "${BASH_SOURCE[0]}")/.. &&pwd) - -source $OPENIM_ROOT/scripts/style_info.sh -source $OPENIM_ROOT/scripts/path_info.sh -source $SCRIPTS_ROOT/function.sh - -service_port_name=( - openImChatApiPort - openImAdminApiPort - #api port name - openImAdminPort - openImChatPort -) - -for i in ${service_port_name[*]}; do - list=$(cat $OPENIM_ROOT/config/config.yaml | grep -w ${i} | awk -F '[:]' '{print $NF}') - list_to_string $list - for j in ${ports_array}; do - name="ps -aux |grep -w $j |grep -v grep" - count="${name}| wc -l" - if [ $(eval ${count}) -gt 0 ]; then - pid="${name}| awk '{print \$2}'" - echo -e "${SKY_BLUE_PREFIX}Killing service:$i pid:$(eval $pid)${COLOR_SUFFIX}" - #kill the service that existed - kill -9 $(eval $pid) - echo -e "${SKY_BLUE_PREFIX}service:$i was killed ${COLOR_SUFFIX}" - fi - done -done \ No newline at end of file diff --git a/openim-chat/scripts/style_info.sh b/openim-chat/scripts/style_info.sh deleted file mode 100644 index 452240035..000000000 --- a/openim-chat/scripts/style_info.sh +++ /dev/null @@ -1,66 +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 style-info() { - COLOR_SUFFIX="\033[0m" # End all colors and special effects - - BLACK_PREFIX="\033[30m" # Black prefix - RED_PREFIX="\033[31m" # Red prefix - GREEN_PREFIX="\033[32m" # Green prefix - YELLOW_PREFIX="\033[33m" # Yellow prefix - BLUE_PREFIX="\033[34m" # Blue prefix - PURPLE_PREFIX="\033[35m" # Purple prefix - SKY_BLUE_PREFIX="\033[36m" # Sky blue prefix - WHITE_PREFIX="\033[37m" # White prefix - BOLD_PREFIX="\033[1m" # Bold prefix - UNDERLINE_PREFIX="\033[4m" # Underline prefix - ITALIC_PREFIX="\033[3m" # Italic prefix - - CYAN_PREFIX="033[0;36m" # Cyan prefix - - BACKGROUND_BLACK="\033[40m" # Black background - BACKGROUND_RED="\033[41m" # Red background - BACKGROUND_GREEN="\033[42m" # Green background - BACKGROUND_YELLOW="\033[43m" # Yellow background - BACKGROUND_BLUE="\033[44m" # Blue background - BACKGROUND_PURPLE="\033[45m" # Purple background - BACKGROUND_SKY_BLUE="\033[46m" # Sky blue background - BACKGROUND_WHITE="\033[47m" # White background - - BLINK="\033[5m" # Blinking effect - INVERT="\033[7m" # Invert color - HIDE="\033[8m" # Hide text - - GRAY_PREFIX="\033[90m" # Gray prefix - LIGHT_RED_PREFIX="\033[91m" # Light red prefix - LIGHT_GREEN_PREFIX="\033[92m" # Light green prefix - LIGHT_YELLOW_PREFIX="\033[93m" # Light yellow prefix - LIGHT_BLUE_PREFIX="\033[94m" # Light blue prefix - LIGHT_PURPLE_PREFIX="\033[95m" # Light purple prefix - LIGHT_SKY_BLUE_PREFIX="\033[96m" # Light sky blue prefix - LIGHT_WHITE_PREFIX="\033[97m" # Light white prefix - - BACKGROUND_GRAY="\033[100m" # Gray background - BACKGROUND_LIGHT_RED="\033[101m" # Light red background - BACKGROUND_LIGHT_GREEN="\033[102m" # Light green background - BACKGROUND_LIGHT_YELLOW="\033[103m" # Light yellow background - BACKGROUND_LIGHT_BLUE="\033[104m" # Light blue background - BACKGROUND_LIGHT_PURPLE="\033[105m" # Light purple background - BACKGROUND_LIGHT_SKY_BLUE="\033[106m" # Light sky blue background - BACKGROUND_LIGHT_WHITE="\033[107m" # Light white background -} - -style-info \ No newline at end of file diff --git a/pkg/apistruct/doc.go b/pkg/apistruct/doc.go new file mode 100644 index 000000000..d99eab7b6 --- /dev/null +++ b/pkg/apistruct/doc.go @@ -0,0 +1,15 @@ +// 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 apistruct // import "github.com/OpenIMSDK/Open-IM-Server/pkg/apistruct" diff --git a/pkg/authverify/doc.go b/pkg/authverify/doc.go new file mode 100644 index 000000000..e07d69614 --- /dev/null +++ b/pkg/authverify/doc.go @@ -0,0 +1,15 @@ +// 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 authverify // import "github.com/OpenIMSDK/Open-IM-Server/pkg/authverify" diff --git a/pkg/callbackstruct/doc.go b/pkg/callbackstruct/doc.go new file mode 100644 index 000000000..d9d9cd8d0 --- /dev/null +++ b/pkg/callbackstruct/doc.go @@ -0,0 +1,15 @@ +// 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 callbackstruct // import "github.com/OpenIMSDK/Open-IM-Server/pkg/callbackstruct" diff --git a/pkg/common/cmd/doc.go b/pkg/common/cmd/doc.go new file mode 100644 index 000000000..75da58c57 --- /dev/null +++ b/pkg/common/cmd/doc.go @@ -0,0 +1,15 @@ +// 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 cmd // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/cmd" diff --git a/pkg/common/config/doc.go b/pkg/common/config/doc.go new file mode 100644 index 000000000..a58dd1b8f --- /dev/null +++ b/pkg/common/config/doc.go @@ -0,0 +1,15 @@ +// 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 config // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/config" diff --git a/pkg/common/convert/doc.go b/pkg/common/convert/doc.go new file mode 100644 index 000000000..0789adc3f --- /dev/null +++ b/pkg/common/convert/doc.go @@ -0,0 +1,15 @@ +// 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 convert // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/convert" diff --git a/pkg/common/db/cache/doc.go b/pkg/common/db/cache/doc.go new file mode 100644 index 000000000..e02c5b9ba --- /dev/null +++ b/pkg/common/db/cache/doc.go @@ -0,0 +1,15 @@ +// 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 cache // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/cache" diff --git a/pkg/common/db/controller/doc.go b/pkg/common/db/controller/doc.go new file mode 100644 index 000000000..d54b689a6 --- /dev/null +++ b/pkg/common/db/controller/doc.go @@ -0,0 +1,15 @@ +// 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 controller // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/controller" diff --git a/pkg/common/db/controller/user.go b/pkg/common/db/controller/user.go index 8e58eb6eb..fcf319ff7 100644 --- a/pkg/common/db/controller/user.go +++ b/pkg/common/db/controller/user.go @@ -180,13 +180,13 @@ func (u *userDatabase) CountRangeEverydayTotal(ctx context.Context, start time.T return u.userDB.CountRangeEverydayTotal(ctx, start, end) } -// SubscribeUsersStatus Subscribe or unsubscribe a user's presence status +// SubscribeUsersStatus Subscribe or unsubscribe a user's presence status. func (u *userDatabase) SubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error { err := u.mongoDB.AddSubscriptionList(ctx, userID, userIDs) return err } -// UnsubscribeUsersStatus unsubscribe a user's presence status +// UnsubscribeUsersStatus unsubscribe a user's presence status. func (u *userDatabase) UnsubscribeUsersStatus(ctx context.Context, userID string, userIDs []string) error { err := u.mongoDB.UnsubscriptionList(ctx, userID, userIDs) return err diff --git a/pkg/common/db/localcache/doc.go b/pkg/common/db/localcache/doc.go new file mode 100644 index 000000000..40afac0ba --- /dev/null +++ b/pkg/common/db/localcache/doc.go @@ -0,0 +1,15 @@ +// 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 localcache // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/localcache" diff --git a/pkg/common/db/relation/doc.go b/pkg/common/db/relation/doc.go new file mode 100644 index 000000000..a3ac7243f --- /dev/null +++ b/pkg/common/db/relation/doc.go @@ -0,0 +1,15 @@ +// 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 relation // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation" diff --git a/pkg/common/db/s3/cont/doc.go b/pkg/common/db/s3/cont/doc.go new file mode 100644 index 000000000..bdba8501b --- /dev/null +++ b/pkg/common/db/s3/cont/doc.go @@ -0,0 +1,15 @@ +// 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 cont // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cont" diff --git a/pkg/common/db/s3/cos/doc.go b/pkg/common/db/s3/cos/doc.go new file mode 100644 index 000000000..bf405d0fc --- /dev/null +++ b/pkg/common/db/s3/cos/doc.go @@ -0,0 +1,15 @@ +// 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 cos // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/cos" diff --git a/pkg/common/db/s3/doc.go b/pkg/common/db/s3/doc.go new file mode 100644 index 000000000..0a3cfe521 --- /dev/null +++ b/pkg/common/db/s3/doc.go @@ -0,0 +1,15 @@ +// 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 s3 // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3" diff --git a/pkg/common/db/s3/minio/doc.go b/pkg/common/db/s3/minio/doc.go new file mode 100644 index 000000000..704e12202 --- /dev/null +++ b/pkg/common/db/s3/minio/doc.go @@ -0,0 +1,15 @@ +// 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 minio // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/minio" diff --git a/pkg/common/db/s3/minio/image.go b/pkg/common/db/s3/minio/image.go index 62d87551e..71db1ea51 100644 --- a/pkg/common/db/s3/minio/image.go +++ b/pkg/common/db/s3/minio/image.go @@ -1,3 +1,17 @@ +// 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 minio import ( diff --git a/pkg/common/db/s3/minio/struct.go b/pkg/common/db/s3/minio/struct.go index 8200a67b1..28b8bfdc3 100644 --- a/pkg/common/db/s3/minio/struct.go +++ b/pkg/common/db/s3/minio/struct.go @@ -1,3 +1,17 @@ +// 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 minio type minioImageInfo struct { diff --git a/pkg/common/db/s3/oss/doc.go b/pkg/common/db/s3/oss/doc.go new file mode 100644 index 000000000..9520a7ed8 --- /dev/null +++ b/pkg/common/db/s3/oss/doc.go @@ -0,0 +1,15 @@ +// 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 oss // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/s3/oss" diff --git a/pkg/common/db/s3/oss/sign.go b/pkg/common/db/s3/oss/sign.go index 60ce43a3e..1bff18f4d 100644 --- a/pkg/common/db/s3/oss/sign.go +++ b/pkg/common/db/s3/oss/sign.go @@ -1,3 +1,17 @@ +// 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 oss import ( diff --git a/pkg/common/db/table/relation/doc.go b/pkg/common/db/table/relation/doc.go new file mode 100644 index 000000000..fe78a700d --- /dev/null +++ b/pkg/common/db/table/relation/doc.go @@ -0,0 +1,15 @@ +// 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 relation // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation" diff --git a/pkg/common/db/table/unrelation/doc.go b/pkg/common/db/table/unrelation/doc.go new file mode 100644 index 000000000..1c0eab222 --- /dev/null +++ b/pkg/common/db/table/unrelation/doc.go @@ -0,0 +1,15 @@ +// 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 unrelation // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/unrelation" diff --git a/pkg/common/db/unrelation/doc.go b/pkg/common/db/unrelation/doc.go new file mode 100644 index 000000000..b36a2406f --- /dev/null +++ b/pkg/common/db/unrelation/doc.go @@ -0,0 +1,15 @@ +// 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 unrelation // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/unrelation" diff --git a/pkg/common/db/unrelation/msg_convert.go b/pkg/common/db/unrelation/msg_convert.go index 8fbcd56e5..a5cf2da4e 100644 --- a/pkg/common/db/unrelation/msg_convert.go +++ b/pkg/common/db/unrelation/msg_convert.go @@ -1,3 +1,17 @@ +// 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 unrelation import ( diff --git a/pkg/common/http/doc.go b/pkg/common/http/doc.go new file mode 100644 index 000000000..33a0d5e5d --- /dev/null +++ b/pkg/common/http/doc.go @@ -0,0 +1,15 @@ +// 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 http // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/http" diff --git a/pkg/common/kafka/doc.go b/pkg/common/kafka/doc.go new file mode 100644 index 000000000..c796db138 --- /dev/null +++ b/pkg/common/kafka/doc.go @@ -0,0 +1,15 @@ +// 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 kafka // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/kafka" diff --git a/pkg/common/locker/doc.go b/pkg/common/locker/doc.go new file mode 100644 index 000000000..c94581aa9 --- /dev/null +++ b/pkg/common/locker/doc.go @@ -0,0 +1,15 @@ +// 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 locker // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/locker" diff --git a/pkg/common/prome/doc.go b/pkg/common/prome/doc.go new file mode 100644 index 000000000..0b82aa7bf --- /dev/null +++ b/pkg/common/prome/doc.go @@ -0,0 +1,15 @@ +// 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 prome // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/prome" diff --git a/pkg/common/startrpc/doc.go b/pkg/common/startrpc/doc.go new file mode 100644 index 000000000..571fd971a --- /dev/null +++ b/pkg/common/startrpc/doc.go @@ -0,0 +1,15 @@ +// 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 startrpc // import "github.com/OpenIMSDK/Open-IM-Server/pkg/common/startrpc" diff --git a/pkg/msgprocessor/doc.go b/pkg/msgprocessor/doc.go new file mode 100644 index 000000000..2f1d0cb44 --- /dev/null +++ b/pkg/msgprocessor/doc.go @@ -0,0 +1,15 @@ +// 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 msgprocessor // import "github.com/OpenIMSDK/Open-IM-Server/pkg/msgprocessor" diff --git a/pkg/rpcclient/doc.go b/pkg/rpcclient/doc.go new file mode 100644 index 000000000..f32f4f322 --- /dev/null +++ b/pkg/rpcclient/doc.go @@ -0,0 +1,15 @@ +// 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 rpcclient // import "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient" diff --git a/pkg/rpcclient/notification/doc.go b/pkg/rpcclient/notification/doc.go new file mode 100644 index 000000000..eea54e59c --- /dev/null +++ b/pkg/rpcclient/notification/doc.go @@ -0,0 +1,15 @@ +// 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 notification // import "github.com/OpenIMSDK/Open-IM-Server/pkg/rpcclient/notification" diff --git a/pkg/statistics/doc.go b/pkg/statistics/doc.go new file mode 100644 index 000000000..4dabe2058 --- /dev/null +++ b/pkg/statistics/doc.go @@ -0,0 +1,15 @@ +// 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 statistics // import "github.com/OpenIMSDK/Open-IM-Server/pkg/statistics" diff --git a/scripts/.spelling_failures b/scripts/.spelling_failures new file mode 100644 index 000000000..5c29b5992 --- /dev/null +++ b/scripts/.spelling_failures @@ -0,0 +1,6 @@ +CHANGELOG +go.mod +go.sum +third_party/ +translations/ +log \ No newline at end of file diff --git a/scripts/LICENSE/LICENSE b/scripts/LICENSE/LICENSE deleted file mode 100644 index 261eeb9e9..000000000 --- a/scripts/LICENSE/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/scripts/LICENSE/LICENSE_TEMPLATES b/scripts/LICENSE/LICENSE_TEMPLATES deleted file mode 100644 index dbc5ce2c8..000000000 --- a/scripts/LICENSE/LICENSE_TEMPLATES +++ /dev/null @@ -1,13 +0,0 @@ -Copyright © {{.Year}} {{.Holder}} 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. diff --git a/scripts/README.md b/scripts/README.md index da21596d6..0be260558 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -1,5 +1,26 @@ # 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) + - [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 @@ -9,19 +30,19 @@ scripts/ │ └── LICENSE_TEMPLATES # Template for license file ├── README.md # Readme file for scripts directory ├── advertise.sh # Script for advertisement services -├── batch_start_all.sh # Script to start all services in batch +├── batch_start-all.sh # Script to start all services in batch ├── build.cmd # Windows build command script -├── build_all_service.sh # Script to build all services +├── build-all-service.sh # Script to build all services ├── build_push_k8s_images.sh # Script to build and push images for Kubernetes -├── check_all.sh # Script to check status of all services +├── check-all.sh # Script to check status of all services ├── common.sh # Contains common functions used by other scripts ├── coverage.awk # AWK script for coverage report generation ├── coverage.sh # Script for generating coverage reports -├── docker_check_service.sh # Docker specific service check script -├── docker_start_all.sh # Script to start all services in a docker environment +├── docker-check-service.sh # Docker specific service check script +├── docker-start-all-all.sh # Script to start all services in a docker environment ├── ensure_tag.sh # Script to ensure proper tagging of docker images ├── enterprise # Scripts specific to enterprise version -│ ├── check_all.sh # Check status of all enterprise services +│ ├── check-all.sh # Check status of all enterprise services │ ├── function.sh # Functions specific to enterprise version │ └── path_info.cfg # Path information configuration for enterprise version ├── env_check.sh # Script to check the environment @@ -32,7 +53,7 @@ scripts/ │ └── pre-push # Script to run before each push ├── init_pwd.sh # Script to initialize password ├── install_im_compose.sh # Script to install IM with Docker Compose -├── install_im_server.sh # Script to install IM server +├── install-im-server.sh # Script to install IM server ├── lib # Library scripts │ ├── color.sh # Script for console color manipulation │ ├── golang.sh # Script for golang related utility functions @@ -52,15 +73,15 @@ scripts/ │ ├── swagger.mk # Make rules for swagger documentation │ └── tools.mk # Make rules for tools and utilities ├── mongo-init.sh # Script to initialize MongoDB -├── msg_gateway_start.sh # Script to start message gateway service -├── msg_transfer_start.sh # Script to start message transfer service +├── openim-msggateway.sh # Script to start message gateway service +├── openim-msgtransfer.sh # Script to start message transfer service ├── path_info.sh # Script containing path information -├── push_start.sh # Script to start push service +├── openim-push.sh # Script to start push service ├── release.sh # Script to perform release process -├── start_all.sh # Script to start all services -├── start_cron.sh # Script to start cron jobs -├── start_rpc_service.sh # Script to start RPC service -├── stop_all.sh # Script to stop all services +├── start-all.sh # Script to start all services +├── openim-crontask.sh # Script to start cron jobs +├── openim-rpc.sh # Script to start RPC service +├── stop-all.sh # Script to stop all services └── style_info.sh # Script containing style related information ``` @@ -68,6 +89,13 @@ The purpose of having a structured scripts directory like this is to make the op 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/conversions/bash_log.md) + ## Supported platforms - Linux x86_64 (linux_amd64) : 64-bit Linux for most desktop and server systems. @@ -84,11 +112,162 @@ Each directory and script in the structure should be understood as a part of a l - 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/conversions/go_code.md) + +Instructions for producing the demo movie: + +```bash +# Create temporary directory +mkdir /tmp/kb-demo +cd /tmp/kb-demo + +asciinema rec +/scripts/demo/run.sh + + to terminate the script + to terminate the asciinema recording + 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= --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 ... +``` + +**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 ... +``` + +**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 ... +``` + +**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 ... +``` + +**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 +``` + ## 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: diff --git a/scripts/advertise.sh b/scripts/advertise.sh index 75f474bfe..165fa397d 100755 --- a/scripts/advertise.sh +++ b/scripts/advertise.sh @@ -13,61 +13,36 @@ # See the License for the specific language governing permissions and # limitations under the License. - set -e set -o pipefail -trap 'echo "Script interrupted."; exit 1' INT +. $(dirname ${BASH_SOURCE})/lib/init.sh -# Function for colored echo -function color_echo() { - COLOR=$1 - shift - echo -e "${COLOR}===> $* ${COLOR_SUFFIX}" -} +trap 'openim::util::onCtrlC' INT -# Color definitions -function openim_color() { - COLOR_SUFFIX="\033[0m" # End all colors and special effects - - BLACK_PREFIX="\033[30m" # Black prefix - RED_PREFIX="\033[31m" # Red prefix - GREEN_PREFIX="\033[32m" # Green prefix - YELLOW_PREFIX="\033[33m" # Yellow prefix - BLUE_PREFIX="\033[34m" # Blue prefix - SKY_BLUE_PREFIX="\033[36m" # Sky blue prefix - WHITE_PREFIX="\033[37m" # White prefix - BOLD_PREFIX="\033[1m" # Bold prefix - UNDERLINE_PREFIX="\033[4m" # Underline prefix - ITALIC_PREFIX="\033[3m" # Italic prefix - - CYAN_PREFIX="\033[0;36m" # Cyan prefix -} - -function print_with_delay() { +print_with_delay() { text="$1" delay="$2" - color="$3" for i in $(seq 0 $((${#text}-1))); do - printf "${color}${text:$i:1}${COLOR_SUFFIX}" + printf "${text:$i:1}" sleep $delay done printf "\n" } -function print_progress() { +print_progress() { total="$1" delay="$2" - color="$3" - printf "${color}[" + printf "[" for i in $(seq 1 $total); do printf "#" sleep $delay done - printf "]${COLOR_SUFFIX}\n" + printf "]\n" } + function openim_logo() { # Set text color to cyan for header and URL echo -e "\033[0;36m" @@ -114,7 +89,8 @@ O:::::::OOO:::::::O p:::::ppppp:::::::pe::::::::e n::::n n::::nII: 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, real-time messaging to your fingertips. And it's about joining a global community of developers, dedicated to pushing the boundaries of what's possible." 0.01 + print_with_delay "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 diff --git a/scripts/batch_start_all.sh b/scripts/batch_start_all.sh index 45ec813c5..5836144aa 100755 --- a/scripts/batch_start_all.sh +++ b/scripts/batch_start_all.sh @@ -16,26 +16,21 @@ #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 -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +set -o errexit +set -o nounset +set -o pipefail + OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/scripts/lib/init.sh" -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -cd $SCRIPTS_ROOT - -echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}" +trap 'openim::util::onCtrlC' INT need_to_start_server_shell=( - "start_rpc_service.sh" - "msg_gateway_start.sh" - "push_start.sh" - "msg_transfer_start.sh" + "oepnim-api.sh" + "openim-rpc.sh" + "openim-msggateway.sh" + "openim-push.sh" + "openim-msgtransfer.sh" ) time=$(date +"%Y-%m-%d %H:%M:%S") diff --git a/scripts/build-all-service.sh b/scripts/build-all-service.sh new file mode 100755 index 000000000..eefca79f9 --- /dev/null +++ b/scripts/build-all-service.sh @@ -0,0 +1,78 @@ +#!/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: `hack/build-go.sh WHAT=cmd/kubelet`. + +set -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/scripts/lib/init.sh" + +# CPU core number +# Check the system type +system_type=$(uname) + +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 diff --git a/scripts/build_all_service.sh b/scripts/build_all_service.sh deleted file mode 100755 index 65724d27c..000000000 --- a/scripts/build_all_service.sh +++ /dev/null @@ -1,151 +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. - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}" - -echo -e "" - -echo -e "${BACKGROUND_BLUE}===============> Building all using make build binary files ${COLOR_SUFFIX}" - -echo -e "" -echo -e "${BOLD_PREFIX}____________________________________________________________ ${COLOR_SUFFIX}" - - -bin_dir="$BIN_DIR" -logs_dir="$OPENIM_ROOT/logs" -sdk_db_dir="$OPENIM_ROOT/db/sdk/" - -echo "==> bin_dir=$bin_dir" -echo "==> logs_dir=$logs_dir" -echo "==> sdk_db_dir=$sdk_db_dir" - -# Automatically created when there is no bin, logs folder -if [ ! -d $logs_dir ]; then - mkdir -p $logs_dir -fi -if [ ! -d $sdk_db_dir ]; then - mkdir -p $sdk_db_dir -fi - -cd $OPENIM_ROOT - -# CPU core number -# Check the system type -system_type=$(uname) - -if [[ "$system_type" == "Darwin" ]]; then - # macOS (using sysctl) - cpu_count=$(sysctl -n hw.ncpu) -elif [[ "$system_type" == "Linux" ]]; then - # Linux (using lscpu) - cpu_count=$(lscpu --parse | grep -E '^([^#].*,){3}[^#]' | sort -u | wc -l) -else - echo "Unsupported operating system: $system_type" - exit 1 -fi -echo -e "${GREEN_PREFIX}======> cpu_count=$cpu_count${COLOR_SUFFIX}" - -# Count the number of concurrent compilations (half the number of cpus) -compile_count=$((cpu_count / 2)) - -# Execute 'make build' run the make command for concurrent compilation -make -j$compile_count build - -if [ $? -ne 0 ]; then - echo "make build Error, script exits" - exit 1 -fi - -# Get the current operating system and architecture -OS=$(uname -s | tr '[:upper:]' '[:lower:]') -ARCH=$(uname -m) - -# Select the repository home directory based on the operating system and architecture -if [[ "$OS" == "darwin" ]]; then - if [[ "$ARCH" == "x86_64" ]]; then - REPO_DIR="darwin/amd64" - else - REPO_DIR="darwin/386" - fi -elif [[ "$OS" == "linux" ]]; then - if [[ "$ARCH" == "x86_64" ]]; then - REPO_DIR="linux/amd64" - elif [[ "$ARCH" == "arm64" ]]; then - REPO_DIR="linux/arm64" - elif [[ "$ARCH" == "mips64" ]]; then - REPO_DIR="linux/mips64" - elif [[ "$ARCH" == "mips64le" ]]; then - REPO_DIR="linux/mips64le" - elif [[ "$ARCH" == "ppc64le" ]]; then - REPO_DIR="linux/ppc64le" - elif [[ "$ARCH" == "s390x" ]]; then - REPO_DIR="linux/s390x" - else - REPO_DIR="linux/386" - fi -elif [[ "$OS" == "windows" ]]; then - if [[ "$ARCH" == "x86_64" ]]; then - REPO_DIR="windows/amd64" - else - REPO_DIR="windows/386" - fi -else - echo -e "${RED_PREFIX}Unsupported OS: $OS${COLOR_SUFFIX}" - exit 1 -fi - -# Determine if all scripts were successfully built -BUILD_SUCCESS=true -FAILED_SCRIPTS=() - -for binary in $(find _output/bin/platforms/$REPO_DIR -type f); do - if [[ ! -x $binary ]]; then - FAILED_SCRIPTS+=("$binary") - BUILD_SUCCESS=false - fi -done - -echo -e " " - -echo -e "${BOLD_PREFIX}=====================> Build Results <=====================${COLOR_SUFFIX}" - -echo -e " " - -if [[ "$BUILD_SUCCESS" == true ]]; then - echo -e "${GREEN_PREFIX}All binaries built successfully.${COLOR_SUFFIX}" -else - echo -e "${RED_PREFIX}Some binary builds failed. Please check the following binary files:${COLOR_SUFFIX}" - for script in "${FAILED_SCRIPTS[@]}"; do - echo -e "${RED_PREFIX}$script${COLOR_SUFFIX}" - done -fi - -echo -e " " - -echo -e "${BOLD_PREFIX}============================================================${COLOR_SUFFIX}" - -echo -e " " diff --git a/scripts/build_push_k8s_images.sh b/scripts/build_push_k8s_images.sh deleted file mode 100755 index a620c7847..000000000 --- a/scripts/build_push_k8s_images.sh +++ /dev/null @@ -1,46 +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. - -version=errcode -repository=${1} -if [[ -z ${repository} ]] -then - echo "repository is empty" - exit 0 -fi - -set +e -echo "repository: ${repository}" -source ./path_info.sh -echo "start to build docker images" -currentPwd=`pwd` -echo ${currentPwd} -i=0 -for path in ${service_source_root[*]} -do - cd ${path} - make build - image="${repository}/${image_names[${i}]}:$version" - echo ${image} - docker build -t $image . -f ./deploy.Dockerfile - echo "build ${image} success" - docker push ${image} - echo "push ${image} success" - echo "==============================" - i=$((i + 1)) - cd ${currentPwd} -done - -echo "build all images success" \ No newline at end of file diff --git a/scripts/check-all.sh b/scripts/check-all.sh new file mode 100755 index 000000000..17fd923c1 --- /dev/null +++ b/scripts/check-all.sh @@ -0,0 +1,83 @@ +#!/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 + +set -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/scripts/install/common.sh" + +OPENIM_VERBOSE=4 + +# OpenIM status +# Elegant printing function +print_services_and_ports() { + local -n service_names=$1 + local -n service_ports=$2 + + echo "+-------------------------+----------+" + echo "| Service Name | Port |" + echo "+-------------------------+----------+" + + for index in "${!service_names[@]}"; do + printf "| %-23s | %-8s |\n" "${service_names[$index]}" "${service_ports[$index]}" + done + + echo "+-------------------------+----------+" +} + + +# 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[@]}" +echo "## Check all dependent service ports" +echo "+++ The port being checked: ${OPENIM_DEPENDENCY_PORT_LISTARIES[@]}" + +set +e +openim::util::check_ports ${OPENIM_DEPENDENCY_PORT_LISTARIES[@]} + +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 + echo "++++ Check all dependent service ports successfully !" +fi +set -e + +echo -e "\n## Check OpenIM service name" +. $(dirname ${BASH_SOURCE})/install/openim-msgtransfer.sh openim::msgtransfer::check + +echo -e "\n## Check all OpenIM service ports" +echo "+++ The port being checked: ${OPENIM_SERVER_PORT_LISTARIES[@]}" +openim::util::check_ports ${OPENIM_SERVER_PORT_LISTARIES[@]} +if [[ $? -ne 0 ]]; then + echo "+++ cat openim log file >>> ${LOG_FILE}" + openim::log::error_exit "The service does not start properly, please check the port, query variable definition!" +else + echo "++++ Check all openim service ports successfully !" +fi \ No newline at end of file diff --git a/scripts/check_all.sh b/scripts/check_all.sh deleted file mode 100755 index 4939057ca..000000000 --- a/scripts/check_all.sh +++ /dev/null @@ -1,80 +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. - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -cd $SCRIPTS_ROOT - -echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}" - -service_port_name=( - openImWsPort - openImApiPort - openImUserPort - openImFriendPort - openImMessagePort - openImMessageGatewayPort - openImGroupPort - openImAuthPort - openImPushPort - openImConversationPort - openImThirdPort -) -for i in ${service_port_name[*]}; do - list=$(cat $config_path | grep -w ${i} | awk -F '[:]' '{print $NF}') - list_to_string $list - for j in ${ports_array}; do - port=$(ss -tunlp| grep openim | awk '{print $5}' | grep -w ${j} | awk -F '[:]' '{print $NF}') - if [[ ${port} -ne ${j} ]]; then - echo -e ${BACKGROUND_GREEN}${i}${COLOR_SUFFIX}${RED_PREFIX}" service does not start normally,not initiated port is "${COLOR_SUFFIX}${BACKGROUND_GREEN}${j}${COLOR_SUFFIX} - echo -e ${RED_PREFIX}"please check $OPENIM_ROOT/logs/openIM.log "${COLOR_SUFFIX} - exit -1 - else - echo -e ${j}${GREEN_PREFIX}" port has been listening,belongs service is "${i}${COLOR_SUFFIX} - fi - done -done - -#Check launched service process -check=$(ps aux | grep -w ./${openim_msgtransfer} | grep -v grep | wc -l) -if [ $check -ge ${msg_transfer_service_num} ]; then - echo -e ${GREEN_PREFIX}"none port has been listening,belongs service is openImMsgTransfer"${COLOR_SUFFIX} -else - echo $check ${msg_transfer_service_num} - echo -e ${RED_PREFIX}"openImMsgTransfer service does not start normally, num err"${COLOR_SUFFIX} - echo -e ${RED_PREFIX}"please check $OPENIM_ROOT/logs/openIM.log "${COLOR_SUFFIX} - exit -1 -fi - - -check=$(ps aux | grep -w ./${cron_task_name} | grep -v grep | wc -l) -if [ $check -ge 1 ]; then - echo -e ${GREEN_PREFIX}"none port has been listening,belongs service is openImCronTask"${COLOR_SUFFIX} -else - echo -e ${RED_PREFIX}"cron_task_name service does not start normally"${COLOR_SUFFIX} - echo -e ${RED_PREFIX}"please check $OPENIM_ROOT/logs/openIM.log "${COLOR_SUFFIX} - exit -1 -fi - -echo -e ${BACKGROUND_GREEN}"all services launch success"${COLOR_SUFFIX} diff --git a/scripts/cherry-pick.sh b/scripts/cherry-pick.sh new file mode 100755 index 000000000..8b81b3401 --- /dev/null +++ b/scripts/cherry-pick.sh @@ -0,0 +1,256 @@ +#!/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/git_cherry-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--- + +set -o errexit +set -o nounset +set -o pipefail + +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(/http[s]:\/\/|git@/,"")}1' | awk -F'[@:./]' 'NR==1{print $3}')} +MAIN_REPO_NAME=${MAIN_REPO_NAME:-$(git remote get-url "$UPSTREAM_REMOTE" | awk '{gsub(/http[s]:\/\/|git@/,"")}1' | awk -F'[@:./]' 'NR==1{print $4}')} + +if [[ -z ${GITHUB_USER:-} ]]; then + openim::log::error_exit "Please export GITHUB_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} ...: cherry pick one or more onto and leave instructions for proposing pull request" + echo + echo " Checks out and handles the cherry-pick of (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/git_cherry-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 <&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 \ No newline at end of file diff --git a/scripts/common.sh b/scripts/common.sh index 6068a1d95..35bcd6e9e 100755 --- a/scripts/common.sh +++ b/scripts/common.sh @@ -37,7 +37,8 @@ readonly DOCKER_MACHINE_DRIVER=${DOCKER_MACHINE_DRIVER:-"virtualbox --virtualbox # This will canonicalize the path OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd -P) -source "${OPENIM_ROOT}/scripts/lib/init.sh" +# Please do not refer to lib after referring to common +. $(dirname ${BASH_SOURCE})/lib/init.sh # Constants readonly OPENIM_BUILD_IMAGE_REPO=openim-build diff --git a/scripts/demo.sh b/scripts/demo.sh new file mode 100755 index 000000000..d074c2c43 --- /dev/null +++ b/scripts/demo.sh @@ -0,0 +1,92 @@ +#!/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. + +clear +. $(dirname ${BASH_SOURCE})/lib/util.sh + +trap 'openim::util::onCtrlC' INT + +openim::util::desc "========> Welcome to the OpenIM Demo" +openim::util::desc "========> We'll help you get started with OpenIM quickly" +openim::util::desc "========> Press Enter to continue...." +openim::util::run "make advertise" +clear + +openim::util::desc "========> Initialize the project and generate configuration files" +openim::util::run "make init" + +openim::util::desc "========> You can look git diff" +openim::util::run "git diff" +clear + +openim::util::desc "You can learn a lot about automation using make help" +openim::util::run "make help" +clear + +openim::util::desc "You can learn a lot about automation using make help-all" +openim::util::run "make help-all" +clear + +openim::util::desc "How did we teach you how to build OpenIM" +openim::util::desc "A full build startup check" +openim::util::run "make all" + +openim::util::desc "Build one OpenIM binary" +openim::util::desc "BINS: openim-api openim-cmdutils openim-crontask openim-msggateway openim-msgtransfer openim-push openim-rpc changelog infra ncpu yamlfmt" +openim::util::run "make build BINS=openim-api" + +openim::util::desc "Build binaries for all platforms" +openim::util::run "make multiarch -j BINS=openim-api PLATFORMS='linux_arm64 linux_amd64' " + +openim::util::desc "If you wish to use dlv for debugging, either binary or process" +openim::util::desc "You need to enable debug mode" +openim::util::run "make build BINS=openim-api DEBUG=1" +clear + +openim::util::desc "Run tidy to format and fix imports" +openim::util::run "make tidy" +clear + +openim::util::desc "Vendor go.mod dependencies" +openim::util::run "make vendor" +clear + +openim::util::desc "Run unit tests" +openim::util::run "make test" +clear + +openim::util::desc "Run unit tests and get test coverage" +openim::util::run "make cover" +clear + +openim::util::desc "Check for updates to go.mod dependencies" +openim::util::run "make updates" +clear + +openim::util::desc "Clean all generated files" +openim::util::run "make clean" +clear + +openim::util::desc "Generate all necessary files" +openim::util::run "make gen" +clear + +openim::util::desc "Verify the license headers for all files" +openim::util::run "make verify-copyright" +clear + +openim::util::desc "Add copyright" +openim::util::run "make add-copyright" +clear diff --git a/scripts/docker_check_service.sh b/scripts/docker-check-service.sh similarity index 80% rename from scripts/docker_check_service.sh rename to scripts/docker-check-service.sh index e2224c8d9..c1fb94748 100755 --- a/scripts/docker_check_service.sh +++ b/scripts/docker-check-service.sh @@ -14,23 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. -Chat_Script=$SCRIPTS_ROOT/../openim-chat/scripts - -source "$SCRIPTS_ROOT/style_info.sh" - -echo -e "${GREEN_PREFIX}=========> Check docker-compose status ${COLOR_SUFFIX} \n" - -trap 'onCtrlC' INT - -function onCtrlC() { - kill -9 "${do_sth_pid}" "${progress_pid}" "${countdown_pid}" - echo - echo 'Ctrl+C is captured' - exit 1 -} +source "${OPENIM_ROOT}/scripts/install/common.sh" cd "$OPENIM_ROOT" @@ -94,9 +79,7 @@ do_sth() { kill "$_progress_pid" "$_countdown_pid" - "${SCRIPTS_ROOT}/check_all.sh" - echo -e "${GREEN_PREFIX}=========> Check chat-compose status ${COLOR_SUFFIX} \n" - "${Chat_Script}/check_all.sh" + "${SCRIPTS_ROOT}/check-all.sh" echo -e "${PURPLE_PREFIX}=========> Check docker-compose status ${COLOR_SUFFIX} \n" } diff --git a/openim-chat/scripts/build_docker.sh b/scripts/docker-start-all.sh old mode 100644 new mode 100755 similarity index 54% rename from openim-chat/scripts/build_docker.sh rename to scripts/docker-start-all.sh index fcd1452d9..a0adfdf0f --- a/openim-chat/scripts/build_docker.sh +++ b/scripts/docker-start-all.sh @@ -1,7 +1,6 @@ #!/usr/bin/env bash - -# Copyright © 2023 OpenIM open source community. All rights reserved. +# 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. @@ -15,22 +14,18 @@ # See the License for the specific language governing permissions and # limitations under the License. -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${SCRIPTS_ROOT}")/.. - - -IMAGE_VERSION=v1.1.0 -image=openim/openim_chat:$IMAGE_VERSION - +#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]}")/.. -chmod +x $OPENIM_ROOT/scripts/*.sh +source "${OPENIM_ROOT}/scripts/install/common.sh" -$OPENIM_ROOT/scripts/build_all_service.sh +trap 'openim::util::onCtrlC' INT -docker build -t $image . -f $OPENIM_ROOT/deploy.Dockerfile +nohup ${OPENIM_ROOT}/scripts/start-all.sh >> ${LOG_FILE} 2>&1 & -docker push $image +sleep 15 -echo -e ${YELLOW_PREFIX}"docker build success"${COLOR_SUFFIX} +nohup ${OPENIM_ROOT}/scripts/check-all.sh >> ${LOG_FILE} 2>&1 & + +tail -f ${LOG_FILE} \ No newline at end of file diff --git a/scripts/docker_start_all.sh b/scripts/docker_start_all.sh deleted file mode 100755 index 24847e21e..000000000 --- a/scripts/docker_start_all.sh +++ /dev/null @@ -1,60 +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 - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -#fixme Put the shell scripts name here -need_to_start_server_shell=( - ${SCRIPTS_ROOT}/start_rpc_service.sh - ${SCRIPTS_ROOT}/msg_gateway_start.sh - ${SCRIPTS_ROOT}/push_start.sh - ${SCRIPTS_ROOT}/msg_transfer_start.sh - ${SCRIPTS_ROOT}/start_cron.sh -) - -component_check=start_component_check.sh -chmod +x $SCRIPTS_ROOT/$component_check -$SCRIPTS_ROOT/$component_check -if [ $? -ne 0 ]; then - # Print error message and exit - echo "${BOLD_PREFIX}${RED_PREFIX}Error executing ${component_check}. Exiting...${COLOR_SUFFIX}" - exit -1 -fi - -#fixme The 10 second delay to start the project is for the docker-compose one-click to start openIM when the infrastructure dependencies are not started - -sleep 10 -time=`date +"%Y-%m-%d %H:%M:%S"` -echo "==========================================================">>$OPENIM_ROOT/logs/openIM.log 2>&1 & -echo "==========================================================">>$OPENIM_ROOT/logs/openIM.log 2>&1 & -echo "==========================================================">>$OPENIM_ROOT/logs/openIM.log 2>&1 & -echo "==========server start time:${time}===========">>$OPENIM_ROOT/logs/openIM.log 2>&1 & -echo "==========================================================">>$OPENIM_ROOT/logs/openIM.log 2>&1 & -echo "==========================================================">>$OPENIM_ROOT/logs/openIM.log 2>&1 & -echo "==========================================================">>$OPENIM_ROOT/logs/openIM.log 2>&1 & -for i in ${need_to_start_server_shell[*]}; do - $i -done - -sleep 15 - -#fixme prevents the openIM service exit after execution in the docker container -tail -f /dev/null diff --git a/scripts/enterprise/check_all.sh b/scripts/enterprise/check_all.sh deleted file mode 100755 index 271dfb452..000000000 --- a/scripts/enterprise/check_all.sh +++ /dev/null @@ -1,52 +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. - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -cd $SCRIPTS_ROOT - -echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}" - -service_port_name=( - openImChatApiPort - openImAdminApiPort - #api port name - openImAdminPort - openImChatPort -) - -for i in ${service_port_name[*]}; do - list=$(cat $config_path | grep -w ${i} | awk -F '[:]' '{print $NF}') - list_to_string $list - for j in ${ports_array}; do - port=$(ss -tunlp| grep openim | awk '{print $5}' | grep -w ${j} | awk -F '[:]' '{print $NF}') - if [[ ${port} -ne ${j} ]]; then - echo -e ${BACKGROUND_GREEN}${i}${COLOR_SUFFIX}${RED_PREFIX}" service does not start normally,not initiated port is "${COLOR_SUFFIX}${BACKGROUND_GREEN}${j}${COLOR_SUFFIX} - echo -e ${RED_PREFIX}"please check $OPENIM_ROOT/logs/openIM.log"${COLOR_SUFFIX} - exit -1 - else - echo -e ${j}${GREEN_PREFIX}" port has been listening,belongs service is "${i}${COLOR_SUFFIX} - fi - done -done diff --git a/scripts/enterprise/path_info.cfg b/scripts/enterprise/path_info.cfg deleted file mode 100644 index 3b18bbf90..000000000 --- a/scripts/enterprise/path_info.cfg +++ /dev/null @@ -1,25 +0,0 @@ -#Don't put the space between "=" - -demo_server_name="chat-api" -demo_server_binary_root="$BIN_DIR/" - -#Global configuration file default dir -config_path="../.docker-compose_cfg/config.yaml" - -#servicefile dir path -service_source_root=( - #api service file - ../cmd/api/chat/ - ../cmd/api/admin/ - #rpc service file - ../cmd/rpc/admin/ - ../cmd/rpc/chat/ -) - -#service filename -service_names=( - chat-api - admin-api - admin-rpc - chat-rpc -) diff --git a/scripts/env_check.sh b/scripts/env_check.sh index 7cd9f83a3..08d6a84b1 100755 --- a/scripts/env_check.sh +++ b/scripts/env_check.sh @@ -19,9 +19,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) OPENIM_ROOT=$(dirname "${SCRIPTS_ROOT}")/.. #Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh +source $SCRIPTS_ROOT/lib/init.sh cd $SCRIPTS_ROOT diff --git a/scripts/environment.sh b/scripts/environment.sh deleted file mode 100755 index 0c2aea971..000000000 --- a/scripts/environment.sh +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2020 Lingfei Kong . All rights reserved. -# Use of this source code is governed by a MIT style -# license that can be found in the LICENSE file. - -# OPENIM 项目源码根目录 -IAM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -# 生成文件存放目录 -LOCAL_OUTPUT_ROOT="${IAM_ROOT}/${OUT_DIR:-_output}" - -# 设置统一的密码,方便记忆 -readonly PASSWORD=${PASSWORD:-'iam59!z$'} - -# Linux系统 going 用户 -readonly LINUX_USERNAME=${LINUX_USERNAME:-going} -# Linux root & going 用户密码 -readonly LINUX_PASSWORD=${LINUX_PASSWORD:-${PASSWORD}} - -# 设置安装目录 -readonly INSTALL_DIR=${INSTALL_DIR:-/tmp/installation} -mkdir -p ${INSTALL_DIR} -readonly ENV_FILE=${IAM_ROOT}/scripts/install/environment.sh - -# MariaDB 配置信息 -readonly MARIADB_ADMIN_USERNAME=${MARIADB_ADMIN_USERNAME:-root} # MariaDB root 用户 -readonly MARIADB_ADMIN_PASSWORD=${MARIADB_ADMIN_PASSWORD:-${PASSWORD}} # MariaDB root 用户密码 -readonly MARIADB_HOST=${MARIADB_HOST:-127.0.0.1:3306} # MariaDB 主机地址 -readonly MARIADB_DATABASE=${MARIADB_DATABASE:-openim} # MariaDB openim 应用使用的数据库名 -readonly MARIADB_USERNAME=${MARIADB_USERNAME:-openim} # openim 数据库用户名 -readonly MARIADB_PASSWORD=${MARIADB_PASSWORD:-${PASSWORD}} # openim 数据库密码 - -# Redis 配置信息 -readonly REDIS_HOST=${REDIS_HOST:-127.0.0.1} # Redis 主机地址 -readonly REDIS_PORT=${REDIS_PORT:-6379} # Redis 监听端口 -readonly REDIS_USERNAME=${REDIS_USERNAME:-''} # Redis 用户名 -readonly REDIS_PASSWORD=${REDIS_PASSWORD:-${PASSWORD}} # Redis 密码 - -# MongoDB 配置 -readonly MONGO_ADMIN_USERNAME=${MONGO_ADMIN_USERNAME:-root} # MongoDB root 用户 -readonly MONGO_ADMIN_PASSWORD=${MONGO_ADMIN_PASSWORD:-${PASSWORD}} # MongoDB root 用户密码 -readonly MONGO_HOST=${MONGO_HOST:-127.0.0.1} # MongoDB 地址 -readonly MONGO_PORT=${MONGO_PORT:-27017} # MongoDB 端口 -readonly MONGO_USERNAME=${MONGO_USERNAME:-openim} # MongoDB 用户名 -readonly MONGO_PASSWORD=${MONGO_PASSWORD:-${PASSWORD}} # MongoDB 密码 - -# openim 配置 -readonly IAM_DATA_DIR=${IAM_DATA_DIR:-/data/openim} # openim 各组件数据目录 -readonly IAM_INSTALL_DIR=${IAM_INSTALL_DIR:-/opt/openim} # openim 安装文件存放目录 -readonly IAM_CONFIG_DIR=${IAM_CONFIG_DIR:-/etc/openim} # openim 配置文件存放目录 -readonly IAM_LOG_DIR=${IAM_LOG_DIR:-/var/log/openim} # openim 日志文件存放目录 -readonly CA_FILE=${CA_FILE:-${IAM_CONFIG_DIR}/cert/ca.pem} # CA - -# openim-apiserver 配置 -readonly IAM_APISERVER_HOST=${IAM_APISERVER_HOST:-127.0.0.1} # openim-apiserver 部署机器 IP 地址 -readonly IAM_APISERVER_GRPC_BIND_ADDRESS=${IAM_APISERVER_GRPC_BIND_ADDRESS:-0.0.0.0} -readonly IAM_APISERVER_GRPC_BIND_PORT=${IAM_APISERVER_GRPC_BIND_PORT:-8081} -readonly IAM_APISERVER_INSECURE_BIND_ADDRESS=${IAM_APISERVER_INSECURE_BIND_ADDRESS:-127.0.0.1} -readonly IAM_APISERVER_INSECURE_BIND_PORT=${IAM_APISERVER_INSECURE_BIND_PORT:-8080} -readonly IAM_APISERVER_SECURE_BIND_ADDRESS=${IAM_APISERVER_SECURE_BIND_ADDRESS:-0.0.0.0} -readonly IAM_APISERVER_SECURE_BIND_PORT=${IAM_APISERVER_SECURE_BIND_PORT:-8443} -readonly IAM_APISERVER_SECURE_TLS_CERT_KEY_CERT_FILE=${IAM_APISERVER_SECURE_TLS_CERT_KEY_CERT_FILE:-${IAM_CONFIG_DIR}/cert/openim-apiserver.pem} -readonly IAM_APISERVER_SECURE_TLS_CERT_KEY_PRIVATE_KEY_FILE=${IAM_APISERVER_SECURE_TLS_CERT_KEY_PRIVATE_KEY_FILE:-${IAM_CONFIG_DIR}/cert/openim-apiserver-key.pem} - -# openim-authz-server 配置 -readonly IAM_AUTHZ_SERVER_HOST=${IAM_AUTHZ_SERVER_HOST:-127.0.0.1} # openim-authz-server 部署机器 IP 地址 -readonly IAM_AUTHZ_SERVER_INSECURE_BIND_ADDRESS=${IAM_AUTHZ_SERVER_INSECURE_BIND_ADDRESS:-127.0.0.1} -readonly IAM_AUTHZ_SERVER_INSECURE_BIND_PORT=${IAM_AUTHZ_SERVER_INSECURE_BIND_PORT:-9090} -readonly IAM_AUTHZ_SERVER_SECURE_BIND_ADDRESS=${IAM_AUTHZ_SERVER_SECURE_BIND_ADDRESS:-0.0.0.0} -readonly IAM_AUTHZ_SERVER_SECURE_BIND_PORT=${IAM_AUTHZ_SERVER_SECURE_BIND_PORT:-9443} -readonly IAM_AUTHZ_SERVER_SECURE_TLS_CERT_KEY_CERT_FILE=${IAM_AUTHZ_SERVER_SECURE_TLS_CERT_KEY_CERT_FILE:-${IAM_CONFIG_DIR}/cert/openim-authz-server.pem} -readonly IAM_AUTHZ_SERVER_SECURE_TLS_CERT_KEY_PRIVATE_KEY_FILE=${IAM_AUTHZ_SERVER_SECURE_TLS_CERT_KEY_PRIVATE_KEY_FILE:-${IAM_CONFIG_DIR}/cert/openim-authz-server-key.pem} -readonly IAM_AUTHZ_SERVER_CLIENT_CA_FILE=${IAM_AUTHZ_SERVER_CLIENT_CA_FILE:-${CA_FILE}} -readonly IAM_AUTHZ_SERVER_RPCSERVER=${IAM_AUTHZ_SERVER_RPCSERVER:-${IAM_APISERVER_HOST}:${IAM_APISERVER_GRPC_BIND_PORT}} - -# openim-pump 配置 -readonly IAM_PUMP_HOST=${IAM_PUMP_HOST:-127.0.0.1} # openim-pump 部署机器 IP 地址 -readonly IAM_PUMP_COLLECTION_NAME=${IAM_PUMP_COLLECTION_NAME:-iam_analytics} -readonly IAM_PUMP_MONGO_URL=${IAM_PUMP_MONGO_URL:-mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOST}:${MONGO_PORT}/${IAM_PUMP_COLLECTION_NAME}?authSource=${IAM_PUMP_COLLECTION_NAME}} - -# openim-watcher配置 -readonly IAM_WATCHER_HOST=${IAM_WATCHER_HOST:-127.0.0.1} # openim-watcher 部署机器 IP 地址 - -# iamctl 配置 -readonly CONFIG_USER_USERNAME=${CONFIG_USER_USERNAME:-admin} -readonly CONFIG_USER_PASSWORD=${CONFIG_USER_PASSWORD:-Admin@2021} -readonly CONFIG_USER_CLIENT_CERTIFICATE=${CONFIG_USER_CLIENT_CERTIFICATE:-${HOME}/.openim/cert/admin.pem} -readonly CONFIG_USER_CLIENT_KEY=${CONFIG_USER_CLIENT_KEY:-${HOME}/.openim/cert/admin-key.pem} -readonly CONFIG_SERVER_ADDRESS=${CONFIG_SERVER_ADDRESS:-${IAM_APISERVER_HOST}:${IAM_APISERVER_SECURE_BIND_PORT}} -readonly CONFIG_SERVER_CERTIFICATE_AUTHORITY=${CONFIG_SERVER_CERTIFICATE_AUTHORITY:-${CA_FILE}} diff --git a/scripts/function.sh b/scripts/function.sh deleted file mode 100755 index ea7b50c5a..000000000 --- a/scripts/function.sh +++ /dev/null @@ -1,34 +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. - -# input: [10023, 2323, 3434] -# output: 10023 2323 3434 - -# 函数功能:将列表转换为字符串,去除空格和括号 -list_to_string() { - ports_list=$* # 获取传入的参数列表 - sub_s1=$(echo $ports_list | sed 's/ //g') # 去除空格 - sub_s2=${sub_s1//,/ } # 将逗号替换为空格 - sub_s3=${sub_s2#*[} # 去除左括号及其之前的内容 - sub_s4=${sub_s3%]*} # 去除右括号及其之后的内容 - ports_array=$sub_s4 # 将处理后的字符串赋值给变量 ports_array -} - -# 函数功能:去除字符串中的空格 -remove_space() { - value=$* # 获取传入的参数 - result=$(echo $value | sed 's/ //g') # 去除空格 -} diff --git a/scripts/gen-swagger-docs.sh b/scripts/gen-swagger-docs.sh new file mode 100755 index 000000000..f0540b3d6 --- /dev/null +++ b/scripts/gen-swagger-docs.sh @@ -0,0 +1,73 @@ +#!/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. + +set -o errexit +set -o nounset +set -o pipefail + +# 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 _ +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="${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 <> 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 <> +sed -i -e 's|<>|link:#_any[any]|g' ./definitions.adoc +sed -i -e 's|<>|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" \ No newline at end of file diff --git a/scripts/genconfig.sh b/scripts/genconfig.sh index cee105a8a..fef411446 100755 --- a/scripts/genconfig.sh +++ b/scripts/genconfig.sh @@ -1,11 +1,21 @@ #!/usr/bin/env bash - -# Copyright 2020 Lingfei Kong . All rights reserved. -# Use of this source code is governed by a MIT style -# license that can be found in the LICENSE file. +# 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. # 本脚本功能:根据 scripts/environment.sh 配置,生成 OPENIM 组件 YAML 配置文件。 -# 示例:genconfig.sh scripts/environment.sh configs/openim-apiserver.yaml +# 示例:./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" @@ -15,7 +25,7 @@ OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. source "${OPENIM_ROOT}/scripts/lib/init.sh" if [ $# -ne 2 ];then - openim::log::error "Usage: genconfig.sh scripts/environment.sh configs/openim-apiserver.yaml" + openim::log::error "Usage: scripts/genconfig.sh scripts/environment.sh configs/openim-api.yaml" exit 1 fi diff --git a/scripts/gendoc.sh b/scripts/gendoc.sh new file mode 100755 index 000000000..1d381483f --- /dev/null +++ b/scripts/gendoc.sh @@ -0,0 +1,78 @@ +#!/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. + +DEFAULT_DIRS=( + "pkg" + "internal/pkg" +) +BASE_URL="github.com/OpenIMSDK/Open-IM-Server" + +usage() { + echo "Usage: $0 [OPTIONS]" + echo + echo "This script iterates over directories and generates doc.go if necessary." + echo "By default, it processes 'pkg' and 'internal/pkg' directories." + echo + echo "Options:" + echo " -d DIRS, --dirs DIRS Specify the directories to be processed, separated by commas. E.g., 'pkg,internal/pkg'." + echo " -u URL, --url URL Set the base URL for the import path. Default is '$BASE_URL'." + echo " -h, --help Show this help message." + echo +} + +process_dir() { + local dir=$1 + local base_url=$2 + + for d in $(find $dir -type d); do + if [ ! -f $d/doc.go ]; then + if ls $d/*.go > /dev/null 2>&1; then + echo $d/doc.go + echo "package $(basename $d) // import \"$base_url/$d\"" > $d/doc.go + fi + fi + done +} + +while [[ $# -gt 0 ]]; do + key="$1" + + case $key in + -d|--dirs) + IFS=',' read -ra DIRS <<< "$2" + shift # shift past argument + shift # shift past value + ;; + -u|--url) + BASE_URL="$2" + shift # shift past argument + shift # shift past value + ;; + -h|--help) + usage + exit 0 + ;; + *) + usage + exit 1 + ;; + esac +done + +DIRS=${DIRS:-${DEFAULT_DIRS[@]}} + +for dir in "${DIRS[@]}"; do + process_dir $dir $BASE_URL +done diff --git a/scripts/githooks/pre-commit b/scripts/githooks/pre-commit index 91f5ad531..7fd21593c 100644 --- a/scripts/githooks/pre-commit +++ b/scripts/githooks/pre-commit @@ -26,7 +26,7 @@ LC_ALL=C local_branch="$(git rev-parse --abbrev-ref HEAD)" -valid_branch_regex="^(main|master|develop|release(-[a-zA-Z0-9._-]+)?)$|(feature|feat|openim|hotfix|test|bug|bot|ci|cicd|style|)\/[a-z0-9._-]+$|^HEAD$" +valid_branch_regex="^(main|master|develop|release(-[a-zA-Z0-9._-]+)?)$|(feature|feat|openim|hotfix|test|bug|bot|refactor|revert|ci|cicd|style|)\/[a-z0-9._-]+$|^HEAD$" YELLOW="\e[93m" GREEN="\e[32m" diff --git a/.golangci.yml b/scripts/golangci.yml similarity index 100% rename from .golangci.yml rename to scripts/golangci.yml diff --git a/scripts/init-config.sh b/scripts/init-config.sh new file mode 100755 index 000000000..b10c75b78 --- /dev/null +++ b/scripts/init-config.sh @@ -0,0 +1,50 @@ +#!/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 the various configuration files +# Read: https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/contrib/init_config.md + +set -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. + +source "${OPENIM_ROOT}/scripts/lib/init.sh" + +# 定义一个配置文件数组,其中包含需要生成的配置文件的名称路径 (en: Define a profile array that contains the name path of the profile to be generated.) +readonly ENV_FILE=${ENV_FILE:-${OPENIM_ROOT}/scripts/install/environment.sh} + +# 定义关联数组,其中键是模板文件,值是对应的输出文件 (en: Defines an associative array where the keys are the template files and the values are the corresponding output files.) +declare -A TEMPLATES=( + ["${OPENIM_ROOT}/deployments/templates/env_template.yaml"]="${OPENIM_ROOT}/.env" + ["${OPENIM_ROOT}/deployments/templates/openim.yaml"]="${OPENIM_ROOT}/config/config.yaml" +) + +for template in "${!TEMPLATES[@]}"; do + output_file=${TEMPLATES[$template]} + + if [[ ! -f "${template}" ]]; then + openim::log::error_exit "template file ${template} does not exist..." + fi + + openim::log::info "Working with template file: ${template} to ${output_file}..." + "${OPENIM_ROOT}/scripts/genconfig.sh" "${ENV_FILE}" "${template}" > "${output_file}" || { + openim::log::error "Error processing template file ${template}" + exit 1 + } +done + +openim::log::success "All configuration files have been successfully generated!" \ No newline at end of file diff --git a/scripts/init-env.sh b/scripts/init-env.sh new file mode 100755 index 000000000..f127a46f3 --- /dev/null +++ b/scripts/init-env.sh @@ -0,0 +1,31 @@ +#!/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 script is the startup script for multiple servers. +#FIXME The full names of the shell scripts that need to be started are placed in the `need_to_start_server_shell` array. + +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd -P) +source "${OPENIM_ROOT}/scripts/install/common.sh" + +for file in "${OPENIM_SERVER_TARGETS[@]}"; do + VARNAME="$(echo $file | tr '[:lower:]' '[:upper:]' | tr '.' '_' | tr '-' '_')" + VARVALUE="$OPENIM_OUTPUT_HOSTBIN/$file" + # /etc/profile.d/openim-env.sh + echo "export $VARNAME=$VARVALUE" > /etc/profile.d/openim-env.sh + source /etc/profile.d/openim-env.sh +done diff --git a/scripts/init_pwd.sh b/scripts/init_pwd.sh index 1e5fa3b34..f2696ea9b 100755 --- a/scripts/init_pwd.sh +++ b/scripts/init_pwd.sh @@ -19,9 +19,8 @@ SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) OPENIM_ROOT=$(dirname "${SCRIPTS_ROOT}")/.. #Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh +source $SCRIPTS_ROOT/lib/init.sh source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh cd $SCRIPTS_ROOT diff --git a/scripts/install-im-server.sh b/scripts/install-im-server.sh new file mode 100755 index 000000000..3e8061151 --- /dev/null +++ b/scripts/install-im-server.sh @@ -0,0 +1,47 @@ +#!/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. + + +# Common utilities, variables and checks for all build scripts. +set -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/scripts/lib/init.sh" + +trap 'openim::util::onCtrlC' INT + +chmod +x ${OPENIM_ROOT}/scripts/*.sh +${OPENIM_ROOT}/scripts/init-config.sh + +openim::util::ensure_docker_daemon_connectivity + +DOCKER_COMPOSE_COMMAND= +# Check if docker-compose command is available +if command -v docker-compose &> /dev/null +then + openim::log::info "docker-compose command is available" + DOCKER_COMPOSE_COMMAND="docker-compose" +else + DOCKER_COMPOSE_COMMAND="docker compose" +fi + +pushd "${OPENIM_ROOT}" >/dev/null + ${DOCKER_COMPOSE_COMMAND} up -d + sleep 60 + ${DOCKER_COMPOSE_COMMAND} ps + ${DOCKER_COMPOSE_COMMAND} logs +popd >/dev/null diff --git a/scripts/install/README.md b/scripts/install/README.md new file mode 100644 index 000000000..8e710add8 --- /dev/null +++ b/scripts/install/README.md @@ -0,0 +1,116 @@ +# OpenIM Suite Scripts + +The OpenIM Suite represents a comprehensive collection of scripts, each tailored to manage and operate specific services within the OpenIM ecosystem. These scripts offer consistent, reliable, and efficient tools for initializing, controlling, and managing various OpenIM services on a Linux platform. + +## Features + +- **Robustness:** Built with Bash's error handling mechanisms (`errexit`, `nounset`, and `pipefail`), ensuring scripts fail fast and provide relevant error messages. +- **Modularity:** Each script is dedicated to a particular service, promoting clarity and ease of maintenance. +- **Comprehensive Logging:** Integrated logging utilities offer real-time insights into operations, enhancing transparency and debuggability. +- **Systemd Integration:** Where applicable, scripts integrate with the systemd service manager, offering standardized service controls like start, stop, restart, and status checks. + +## Scripts Overview + +1. **openim-api:** Control interface for the OpenIM API service. +2. **openim-cmdutils:** Utility toolkit for common OpenIM command-line operations. +3. **openim-crontask:** Manages the OpenIM CronTask service, with both direct and systemctl installation methods. +4. **openim-msggateway:** Script to operate the OpenIM Message Gateway service. +5. **openim-msgtransfer:** Manages the OpenIM Message Transfer functionalities. +6. **openim-push:** Interface for controlling the OpenIM Push Notification service. +7. **openim-rpc-auth:** Script dedicated to the OpenIM RPC Authentication service. +8. **openim-rpc-conversation:** Manages operations related to the OpenIM RPC Conversation service. +9. **openim-rpc-friend:** Control interface for the OpenIM RPC Friend functionalities. +10. **openim-rpc-group:** Script for managing the OpenIM RPC Group service. +11. **openim-rpc-msg:** Operates the OpenIM RPC Messaging service. +12. **openim-rpc-third:** Script dedicated to third-party integrations with OpenIM RPC. +13. **openim-rpc-user:** Control interface for OpenIM RPC User operations. + +## OpenIM Server Installation Script Usage + +The scripts within the OpenIM Suite generally adhere to two primary execution methodologies. To illustrate these methodologies, we'll use `openim-crontask` as a representative example. + +1. **Direct Script Execution:** Running the script directly, typically for straightforward start/stop operations. + + ```bash + ./[script-name].sh + ``` + +2. **Function-based Execution:** Invoking specific functions within the script for more specialized operations (e.g., install, uninstall). + + ```bash + ./scripts/install/install.sh [options] + ``` + +**Description:** +This script is designed to handle the installation, uninstallation, and status checking of OpenIM components on the server. OpenIM is a presumed communication or messaging platform. + +### Commands: +- **-i, --install**: + Initiate the installation of all OpenIM components. + +- **-u, --uninstall**: + Uninstall or remove all OpenIM components from the server. + +- **-s, --status**: + Check and report the current operational status of the installed OpenIM components. + +- **-h, --help**: + Display the help menu for available commands. + +### Example Usage: +To install all OpenIM components: +```bash +./scripts/install/install.sh -i +``` +or +```bash +./scripts/install/install.sh --install +``` +> **Note**: +> Ensure you have the necessary privileges to execute installation or uninstallation operations. It's generally recommended to take a backup before making major changes. + + +### 1. Direct Script Execution + +This method involves invoking the script directly, initiating its default behavior. For instance, with `openim-crontask`, direct execution will start the OpenIM CronTask as a background process. + +**Example:** + +```bash +./openim-crontask.sh +``` + +Upon execution, the script will source any necessary configurations, log the start of the CronTask, and finally run the CronTask in the background. The log messages will provide feedback about the process, ensuring the user is informed of the task's progress. + +### 2. Function-based Execution + +This approach is more specialized, enabling users to call specific functions defined within the script. This is particularly useful for tasks like installation, uninstallation, and status checks. + +For the `openim-crontask` script: + +- **Installation**: It includes building the service, generating configuration files, setting up systemd services, and starting the service. + + ```bash + ./openim-crontask.sh openim::crontask::install + ``` + +- **Uninstallation**: Stops the service, removes associated binaries, configuration files, and systemd service files. + + ```bash + ./openim-crontask.sh openim::crontask::uninstall + ``` + +- **Status Check**: Verifies the running status of the service, checking for active processes and listening ports. + + ```bash + ./openim-crontask.sh openim::crontask::status + ``` + +It's crucial to familiarize oneself with the available functions within each script. This ensures optimal utilization of the provided tools and a deeper understanding of the underlying operations. + + + +## Notes + +- Always ensure you have the correct permissions before executing any script. +- Environment variables may need to be set or sourced depending on your installation and configuration. \ No newline at end of file diff --git a/scripts/install/common.sh b/scripts/install/common.sh new file mode 100755 index 000000000..dd8bf614e --- /dev/null +++ b/scripts/install/common.sh @@ -0,0 +1,142 @@ +#!/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. + + +# Common utilities, variables and checks for all build scripts. +set -o errexit +set +o nounset +set -o pipefail + +# Sourced flag +COMMON_SOURCED=true +# The root of the build/dist directory +OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P) +source "${OPENIM_ROOT}/scripts/lib/init.sh" +# Make sure the environment is only called via common to avoid too much nesting +source "${OPENIM_ROOT}/scripts/install/environment.sh" + +# This function returns a list of Prometheus ports for various services +# based on the provided configuration. Each service has its own dedicated +# port for monitoring purposes. +openim::common::prometheus_port() { + # Declare an array to hold all the Prometheus ports for different services + local targets=( + ${USER_PROM_PORT} # Prometheus port for user service + ${FRIEND_PROM_PORT} # Prometheus port for friend service + ${MESSAGE_PROM_PORT} # Prometheus port for message service + ${MSG_GATEWAY_PROM_PORT} # Prometheus port for message gateway service + ${GROUP_PROM_PORT} # Prometheus port for group service + ${AUTH_PROM_PORT} # Prometheus port for authentication service + ${PUSH_PROM_PORT} # Prometheus port for push notification service + ${CONVERSATION_PROM_PORT} # Prometheus port for conversation service + ${RTC_PROM_PORT} # Prometheus port for real-time communication service + ${THIRD_PROM_PORT} # Prometheus port for third-party integrations service + ${MSG_TRANSFER_PROM_PORT} # Prometheus port for message transfer service + ) + # Print the list of ports + echo "${targets[@]}" +} +IFS=" " read -ra OPENIM_PROM_PORT_TARGETS <<< "$(openim::common::prometheus_port)" +readonly OPENIM_PROM_PORT_TARGETS +readonly OPENIM_PROM_PORT_LISTARIES=("${OPENIM_PROM_PORT_TARGETS[@]##*/}") + +openim::common::service_name() { + local targets=( + openim-user + openim-friend + openim-msg + openim-msg-gateway + openim-group + openim-auth + openim-push + openim-conversation + openim-third + # openim-msg-transfer + + # api + openim-api + openim-ws + ) + echo "${targets[@]}" +} + +IFS=" " read -ra OPENIM_SERVER_NAME_TARGETS <<< "$(openim::common::service_name)" +readonly OPENIM_SERVER_NAME_TARGETS + +# Storing all the defined ports in an array for easy management and access. +# This array consolidates the port numbers for all the services defined above. +openim::common::service_port() { + local targets=( + ${OPENIM_USER_PORT} # User service + ${OPENIM_FRIEND_PORT} # Friend service + ${OPENIM_MESSAGE_PORT} # Message service + ${OPENIM_MESSAGE_GATEWAY_PORT} # Message gateway + ${OPENIM_GROUP_PORT} # Group service + ${OPENIM_AUTH_PORT} # Authorization service + ${OPENIM_PUSH_PORT} # Push service + ${OPENIM_CONVERSATION_PORT} # Conversation service + ${OPENIM_THIRD_PORT} # Third-party service + + # API PORT + ${API_OPENIM_PORT} # API service + ${OPENIM_WS_PORT} # WebSocket service + ) + echo "${targets[@]}" +} +IFS=" " read -ra OPENIM_SERVER_PORT_TARGETS <<< "$(openim::common::service_port)" +readonly OPENIM_SERVER_PORT_TARGETS +readonly OPENIM_SERVER_PORT_LISTARIES=("${OPENIM_SERVER_PORT_TARGETS[@]##*/}") + +openim::common::dependency_name() { + local targets=( + mysql + redis + zookeeper + kafka + mongodb + minio + ) + echo "${targets[@]}" +} + +IFS=" " read -ra OPENIM_DEPENDENCY_TARGETS <<< "$(openim::common::dependency_name)" +readonly OPENIM_DEPENDENCY_TARGETS + +# This function returns a list of ports for various services +# - zookeeper +# - kafka +# - mysql +# - mongodb +# - redis +# - minio +openim::common::dependency_port() { + local targets=( + ${MYSQL_PORT} # MySQL port + ${REDIS_PORT} # Redis port + ${ZOOKEEPER_PORT} # Zookeeper port + ${KAFKA_PORT} # Kafka port + ${MONGO_PORT} # MongoDB port + ${MINIO_PORT} # MinIO port + ) + echo "${targets[@]}" +} +IFS=" " read -ra OPENIM_DEPENDENCY_PORT_TARGETS <<< "$(openim::common::dependency_port)" +readonly OPENIM_DEPENDENCY_PORT_TARGETS +readonly OPENIM_DEPENDENCY_PORT_LISTARIES=("${OPENIM_DEPENDENCY_PORT_TARGETS[@]##*/}") + +# Execute commands that require root permission without entering a password +function openim::common::sudo { + echo ${LINUX_PASSWORD} | sudo -S $1 +} diff --git a/scripts/install/dependency.sh b/scripts/install/dependency.sh new file mode 100755 index 000000000..5500df092 --- /dev/null +++ b/scripts/install/dependency.sh @@ -0,0 +1,100 @@ +#!/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 will install the dependencies required for openim + +set -o errexit +set +o nounset +set -o pipefail + +OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P) +[[ -z ${COMMON_SOURCED} ]] && source ${OPENIM_ROOT}/scripts/install/common.sh + +# Start MySQL service +docker run -d \ + --name mysql \ + -p 13306:3306 \ + -p 23306:33060 \ + -v "${DATA_DIR}/components/mysql/data:/var/lib/mysql" \ + -v "/etc/localtime:/etc/localtime" \ + -e MYSQL_ROOT_PASSWORD=${PASSWORD} \ + --restart always \ + mysql:5.7 + +# Start MongoDB service +docker run -d \ + --name mongo \ + -p 37017:27017 \ + -v "${DATA_DIR}/components/mongodb/data/db:/data/db" \ + -v "${DATA_DIR}/components/mongodb/data/logs:/data/logs" \ + -v "${DATA_DIR}/components/mongodb/data/conf:/etc/mongo" \ + -v "./scripts/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh:ro" \ + -e TZ=Asia/Shanghai \ + -e wiredTigerCacheSizeGB=1 \ + -e MONGO_INITDB_ROOT_USERNAME=${USER} \ + -e MONGO_INITDB_ROOT_PASSWORD=${PASSWORD} \ + -e MONGO_INITDB_DATABASE=openIM \ + -e MONGO_USERNAME=${USER} \ + -e MONGO_PASSWORD=${PASSWORD} \ + --restart always \ + mongo:6.0.2 --wiredTigerCacheSizeGB 1 --auth + +# Start Redis service +docker run -d \ + --name redis \ + -p 16379:6379 \ + -v "${DATA_DIR}/components/redis/data:/data" \ + -v "${DATA_DIR}/components/redis/config/redis.conf:/usr/local/redis/config/redis.conf" \ + -e TZ=Asia/Shanghai \ + --sysctl net.core.somaxconn=1024 \ + --restart always \ + redis:7.0.0 redis-server --requirepass ${PASSWORD} --appendonly yes + +# Start Zookeeper service +docker run -d \ + --name zookeeper \ + -p 2181:2181 \ + -v "/etc/localtime:/etc/localtime" \ + -e TZ=Asia/Shanghai \ + --restart always \ + wurstmeister/zookeeper + +# Start Kafka service +docker run -d \ + --name kafka \ + -p 9092:9092 \ + -e TZ=Asia/Shanghai \ + -e KAFKA_BROKER_ID=0 \ + -e KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181 \ + -e KAFKA_CREATE_TOPICS="latestMsgToRedis:8:1,msgToPush:8:1,offlineMsgToMongoMysql:8:1" \ + -e KAFKA_ADVERTISED_LISTENERS="INSIDE://127.0.0.1:9092,OUTSIDE://103.116.45.174:9092" \ + -e KAFKA_LISTENERS="INSIDE://:9092,OUTSIDE://:9093" \ + -e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP="INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT" \ + -e KAFKA_INTER_BROKER_LISTENER_NAME=INSIDE \ + --restart always \ + --link zookeeper \ + wurstmeister/kafka + +# Start MinIO service +docker run -d \ + --name minio \ + -p 10005:9000 \ + -p 9090:9090 \ + -v "/mnt/data:/data" \ + -v "/mnt/config:/root/.minio" \ + -e MINIO_ROOT_USER=${USER} \ + -e MINIO_ROOT_PASSWORD=${PASSWORD} \ + --restart always \ + minio/minio server /data --console-address ':9090' diff --git a/scripts/install/environment.sh b/scripts/install/environment.sh new file mode 100755 index 000000000..79e3e0dcc --- /dev/null +++ b/scripts/install/environment.sh @@ -0,0 +1,415 @@ +#!/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 is a file that initializes variables for the automation script that initializes the config file +# You need to supplement the script according to the specification. +# Read: https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/contrib/init_config.md +# 格式化 bash 注释:https://tool.lu/shell/ + +OPENIM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)" + +# 生成文件存放目录 +LOCAL_OUTPUT_ROOT="${OPENIM_ROOT}/${OUT_DIR:-_output}" +source "${OPENIM_ROOT}/scripts/lib/init.sh" + +#TODO +# IP=http://127.0.0.1 +if [ -z "${IP}" ]; then + IP=$(openim::util::get_server_ip) +fi + +function def() { + local var_name="$1" + local default_value="${2:-}" + eval "readonly $var_name=\"\${$var_name:-$(printf '%q' "$default_value")}\"" +} + +# app要能访问到此ip和端口或域名 +def "API_URL" "http://${IP}:10002" +def "DATA_DIR" "${OPENIM_ROOT}" + +# 设置统一的用户名,方便记忆 +def "USER" "root" + +# 设置统一的密码,方便记忆 +def "PASSWORD" "openIM123" + +# 设置统一的数据库名称,方便管理 +def "DATABASE_NAME" "openIM_v3" + +# Linux系统 openim 用户 +def "LINUX_USERNAME" "openim" +def "LINUX_PASSWORD" "${PASSWORD}" + +# 设置安装目录 +def "INSTALL_DIR" "${LOCAL_OUTPUT_ROOT}/installs" +mkdir -p ${INSTALL_DIR} + +def "ENV_FILE" "${OPENIM_ROOT}/scripts/install/environment.sh" + +###################### openim 配置 ###################### +# read: https://github.com/OpenIMSDK/Open-IM-Server/blob/main/deployment/init/README.md +def "OPENIM_DATA_DIR" "/data/openim" +def "OPENIM_INSTALL_DIR" "/opt/openim" +def "OPENIM_CONFIG_DIR" "/etc/openim" +def "OPENIM_LOG_DIR" "/var/log/openim" +def "CA_FILE" "${OPENIM_CONFIG_DIR}/cert/ca.pem" + +def "OPNEIM_CONFIG" "${OPENIM_ROOT}/config" +# TODO 注意: 一般的配置都可以使用 def 函数来定义,如果是包含特殊字符,比如说: +# TODO readonly MSG_DESTRUCT_TIME=${MSG_DESTRUCT_TIME:-'0 2 * * *'} +# TODO 使用 readonly 来定义合适,负责无法正常解析, 并且 yaml 模板需要加 "" 来包裹 + +###################### Zookeeper 配置信息 ###################### +def "ZOOKEEPER_SCHEMA" "openim" # Zookeeper的模式 +def "ZOOKEEPER_PORT" "2181" # Zookeeper的端口 +def "ZOOKEEPER_ADDRESS" "127.0.0.1" # Zookeeper的地址 +def "ZOOKEEPER_USERNAME" "" # Zookeeper的用户名 +def "ZOOKEEPER_PASSWORD" "" # Zookeeper的密码 + +###################### MySQL 配置信息 ###################### +def "MYSQL_PORT" "13306" # MySQL的端口 +def "MYSQL_ADDRESS" "127.0.0.1" # MySQL的地址 +def "MYSQL_USERNAME" "${USER}" # MySQL的用户名 +def "MYSQL_PASSWORD" "${PASSWORD}" # MySQL的密码 +def "MYSQL_DATABASE" "${DATABASE_NAME}" # MySQL的数据库名 +def "MYSQL_MAX_OPEN_CONN" "1000" # 最大打开的连接数 +def "MYSQL_MAX_IDLE_CONN" "100" # 最大空闲连接数 +def "MYSQL_MAX_LIFETIME" "60" # 连接可以重用的最大生命周期(秒) +def "MYSQL_LOG_LEVEL" "4" # 日志级别 +def "MYSQL_SLOW_THRESHOLD" "500" # 慢查询阈值(毫秒) + +###################### MongoDB 配置信息 ###################### +def "MONGO_URI" # MongoDB的URI +def "MONGO_PORT" "37017" # MongoDB的端口 +def "MONGO_ADDRESS" "127.0.0.1" # MongoDB的地址 +def "MONGO_DATABASE" "${DATABASE_NAME}" # MongoDB的数据库名 +def "MONGO_USERNAME" "${USER}" # MongoDB的用户名 +def "MONGO_PASSWORD" "${PASSWORD}" # MongoDB的密码 +def "MONGO_MAX_POOL_SIZE" "100" # 最大连接池大小 + +###################### Object 配置信息 ###################### +def "OBJECT_ENABLE" "minio" # 对象是否启用 +def "OBJECT_APIURL" "http://${IP}:10002" # 对象的API地址 +def "MINIO_BUCKET" "openim" # MinIO的存储桶名称 +def "MINIO_PORT" "10005" # MinIO的端口 +# MinIO的端点URL +readonly MINIO_ENDPOINT=${MINIO_ENDPOINT:-"http://127.0.0.1:${MINIO_PORT}"} +def "MINIO_ACCESS_KEY" "${USER}" # MinIO的访问密钥ID +def "MINIO_SECRET_KEY" "${PASSWORD}" # MinIO的密钥 +def "MINIO_SESSION_TOKEN" # MinIO的会话令牌 +readonly MINIO_SIGN_ENDPOINT=${MINIO_SIGN_ENDPOINT:-"http://${IP}:${MINIO_PORT}"} # signEndpoint为minio公网地址 # MinIO的会话令牌 +def "COS_BUCKET_URL" "https://temp-1252357374.cos.ap-chengdu.myqcloud.com" # 腾讯云COS的存储桶URL +def "COS_SECRET_ID" # 腾讯云COS的密钥ID +def "COS_SECRET_KEY" # 腾讯云COS的密钥 +def "COS_SESSION_TOKEN" # 腾讯云COS的会话令牌 +def "OSS_ENDPOINT" "https://oss-cn-chengdu.aliyuncs.com" # 阿里云OSS的端点URL +def "OSS_BUCKET" "demo-9999999" # 阿里云OSS的存储桶名称 +def "OSS_BUCKET_URL" "https://demo-9999999.oss-cn-chengdu.aliyuncs.com" # 阿里云OSS的存储桶URL +def "OSS_ACCESS_KEY_ID" # 阿里云OSS的访问密钥ID +def "OSS_ACCESS_KEY_SECRET" # 阿里云OSS的密钥 +def "OSS_SESSION_TOKEN" # 阿里云OSS的会话令牌 + +###################### Redis 配置信息 ###################### +def "REDIS_PORT" "16379" # Redis的端口 +def "REDIS_ADDRESS" "127.0.0.1" # Redis的地址 +def "REDIS_USERNAME" # Redis的用户名 +def "REDIS_PASSWORD" "${PASSWORD}" # Redis的密码 + +###################### Kafka 配置信息 ###################### +def "KAFKA_USERNAME" # Kafka的用户名 +def "KAFKA_PASSWORD" # Kafka的密码 +def "KAFKA_PORT" "9092" # Kafka的端口 +def "KAFKA_ADDR" "127.0.0.1" # Kafka的地址 +def "KAFKA_LATESTMSG_REDIS_TOPIC" "latestMsgToRedis" # Kafka的最新消息到Redis的主题 +def "KAFKA_OFFLINEMSG_MONGO_TOPIC" "offlineMsgToMongoMysql" # Kafka的离线消息到Mongo的主题 +def "KAFKA_MSG_PUSH_TOPIC" "msgToPush" # Kafka的消息到推送的主题 +def "KAFKA_CONSUMERGROUPID_REDIS" "redis" # Kafka的消费组ID到Redis +def "KAFKA_CONSUMERGROUPID_MONGO" "mongo" # Kafka的消费组ID到Mongo +def "KAFKA_CONSUMERGROUPID_MYSQL" "mysql" # Kafka的消费组ID到MySql +def "KAFKA_CONSUMERGROUPID_PUSH" "push" # Kafka的消费组ID到推送 + +###################### RPC 配置信息 ###################### +def "RPC_REGISTER_IP" # RPC的注册IP +def "RPC_LISTEN_IP" "0.0.0.0" # RPC的监听IP + +###################### API 配置信息 ###################### +# API的开放端口, 只能设置一个端口 +def "API_OPENIM_PORT" "10002" +def "API_LISTEN_IP" "0.0.0.0" # API的监听IP + +###################### RPC Port Configuration Variables ###################### +# For launching multiple programs, just fill in multiple ports separated by commas +# For example: +# readonly OPENIM_USER_PORT=${OPENIM_USER_PORT:-'10110, 10111, 10112'} #Try not to have Spaces + +# OpenIM用户服务端口 +readonly OPENIM_USER_PORT=${OPENIM_USER_PORT:-'10110'} +# OpenIM朋友服务端口 +readonly OPENIM_FRIEND_PORT=${OPENIM_FRIEND_PORT:-'10120'} +# OpenIM消息服务端口 +readonly OPENIM_MESSAGE_PORT=${OPENIM_MESSAGE_PORT:-'10130'} +# OpenIM消息网关服务端口 +readonly OPENIM_MESSAGE_GATEWAY_PORT=${OPENIM_MESSAGE_GATEWAY_PORT:-'10140'} +# OpenIM组服务端口 +readonly OPENIM_GROUP_PORT=${OPENIM_GROUP_PORT:-'10150'} +# OpenIM授权服务端口 +readonly OPENIM_AUTH_PORT=${OPENIM_AUTH_PORT:-'10160'} +# OpenIM推送服务端口 +readonly OPENIM_PUSH_PORT=${OPENIM_PUSH_PORT:-'10170'} +# OpenIM对话服务端口 +readonly OPENIM_CONVERSATION_PORT=${OPENIM_CONVERSATION_PORT:-'10180'} +# OpenIM第三方服务端口 +readonly OPENIM_THIRD_PORT=${OPENIM_THIRD_PORT:-'10190'} + +###################### RPC Register Name Variables ###################### +def "OPENIM_USER_NAME" "User" # OpenIM用户服务名称 +def "OPENIM_FRIEND_NAME" "Friend" # OpenIM朋友服务名称 +def "OPENIM_MSG_NAME" "Msg" # OpenIM消息服务名称 +def "OPENIM_PUSH_NAME" "Push" # OpenIM推送服务名称 +def "OPENIM_MESSAGE_GATEWAY_NAME" "MessageGateway" # OpenIM消息网关服务名称 +def "OPENIM_GROUP_NAME" "Group" # OpenIM组服务名称 +def "OPENIM_AUTH_NAME" "Auth" # OpenIM授权服务名称 +def "OPENIM_CONVERSATION_NAME" "Conversation" # OpenIM对话服务名称 +def "OPENIM_THIRD_NAME" "Third" # OpenIM第三方服务名称 + +###################### Log Configuration Variables ###################### +def "LOG_STORAGE_LOCATION" "${OPENIM_ROOT}/logs/" # 日志存储位置 +def "LOG_ROTATION_TIME" "24" # 日志轮替时间 +def "LOG_REMAIN_ROTATION_COUNT" "2" # 保留的日志轮替数量 +def "LOG_REMAIN_LOG_LEVEL" "6" # 保留的日志级别 +def "LOG_IS_STDOUT" "false" # 是否将日志输出到标准输出 +def "LOG_IS_JSON" "false" # 日志是否为JSON格式 +def "LOG_WITH_STACK" "false" # 日志是否带有堆栈信息 + +###################### Variables definition ###################### +def "OPENIM_WS_PORT" "10001" # OpenIM WS端口 +def "WEBSOCKET_MAX_CONN_NUM" "100000" # Websocket最大连接数 +def "WEBSOCKET_MAX_MSG_LEN" "4096" # Websocket最大消息长度 +def "WEBSOCKET_TIMEOUT" "10" # Websocket超时 +def "PUSH_ENABLE" "getui" # 推送是否启用 +# GeTui推送URL +readonly GETUI_PUSH_URL=${GETUI_PUSH_URL:-'https://restapi.getui.com/v2/$appId'} +def "FCM_SERVICE_ACCOUNT" "x.json" # FCM服务账户 +def "JPNS_APP_KEY" # JPNS应用密钥 +def "JPNS_MASTER_SECRET" # JPNS主密钥 +def "JPNS_PUSH_URL" # JPNS推送URL +def "JPNS_PUSH_INTENT" # JPNS推送意图 +def "MANAGER_USERID_1" "openIM123456" # 管理员ID 1 +def "MANAGER_USERID_2" "openIM654321" # 管理员ID 2 +def "MANAGER_USERID_3" "openIMAdmin" # 管理员ID 3 +def "NICKNAME_1" "system1" # 昵称1 +def "NICKNAME_2" "system2" # 昵称2 +def "NICKNAME_3" "system3" # 昵称3 +def "MULTILOGIN_POLICY" "1" # 多登录策略 +def "CHAT_PERSISTENCE_MYSQL" "true" # 聊天持久化MySQL +def "MSG_CACHE_TIMEOUT" "86400" # 消息缓存超时 +def "GROUP_MSG_READ_RECEIPT" "true" # 群消息已读回执启用 +def "SINGLE_MSG_READ_RECEIPT" "true" # 单一消息已读回执启用 +def "RETAIN_CHAT_RECORDS" "365" # 保留聊天记录 +# 聊天记录清理时间 +readonly CHAT_RECORDS_CLEAR_TIME=${CHAT_RECORDS_CLEAR_TIME:-'0 2 * * 3'} +# 消息销毁时间 +readonly MSG_DESTRUCT_TIME=${MSG_DESTRUCT_TIME:-'0 2 * * *'} +def "SECRET" "${PASSWORD}" # 密钥 +def "TOKEN_EXPIRE" "90" # Token到期时间 +def "FRIEND_VERIFY" "false" # 朋友验证 +def "IOS_PUSH_SOUND" "xxx" # IOS推送声音 +def "IOS_BADGE_COUNT" "true" # IOS徽章计数 +def "IOS_PRODUCTION" "false" # IOS生产 + +###################### Prometheus 配置信息 ###################### +def "PROMETHEUS_ENABLE" "false" # 是否启用 Prometheus +def "USER_PROM_PORT" "20110" # User 服务的 Prometheus 端口 +def "FRIEND_PROM_PORT" "20120" # Friend 服务的 Prometheus 端口 +def "MESSAGE_PROM_PORT" "20130" # Message 服务的 Prometheus 端口 +def "MSG_GATEWAY_PROM_PORT" "20140" # Message Gateway 服务的 Prometheus 端口 +def "GROUP_PROM_PORT" "20150" # Group 服务的 Prometheus 端口 +def "AUTH_PROM_PORT" "20160" # Auth 服务的 Prometheus 端口 +def "PUSH_PROM_PORT" "20170" # Push 服务的 Prometheus 端口 +def "CONVERSATION_PROM_PORT" "20230" # Conversation 服务的 Prometheus 端口 +def "RTC_PROM_PORT" "21300" # RTC 服务的 Prometheus 端口 +def "THIRD_PROM_PORT" "21301" # Third 服务的 Prometheus 端口 +# Message Transfer 服务的 Prometheus 端口列表 +readonly MSG_TRANSFER_PROM_PORT=${MSG_TRANSFER_PROM_PORT:-'21400, 21401, 21402, 21403'} + +###################### OpenIM openim-api ###################### +def "OPENIM_API_HOST" "127.0.0.1" +def "OPENIM_API_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-api" # OpenIM openim-api 二进制文件路径 +def "OPENIM_API_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-api 配置文件路径 +def "OPENIM_API_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-api" # OpenIM openim-api 日志存储路径 +def "OPENIM_API_LOG_LEVEL" "info" # OpenIM openim-api 日志级别 +def "OPENIM_API_LOG_MAX_SIZE" "100" # OpenIM openim-api 日志最大大小(MB) +def "OPENIM_API_LOG_MAX_BACKUPS" "7" # OpenIM openim-api 日志最大备份数 +def "OPENIM_API_LOG_MAX_AGE" "7" # OpenIM openim-api 日志最大保存时间(天) +def "OPENIM_API_LOG_COMPRESS" "false" # OpenIM openim-api 日志是否压缩 +def "OPENIM_API_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-api 日志是否带有堆栈信息 + +###################### OpenIM openim-cmdutils ###################### +def "OPENIM_CMDUTILS_HOST" "127.0.0.1" +def "OPENIM_CMDUTILS_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-cmdutils" # OpenIM openim-cmdutils 二进制文件路径 +def "OPENIM_CMDUTILS_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-cmdutils 配置文件路径 +def "OPENIM_CMDUTILS_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-cmdutils" # OpenIM openim-cmdutils 日志存储路径 +def "OPENIM_CMDUTILS_LOG_LEVEL" "info" # OpenIM openim-cmdutils 日志级别 +def "OPENIM_CMDUTILS_LOG_MAX_SIZE" "100" # OpenIM openim-cmdutils 日志最大大小(MB) +def "OPENIM_CMDUTILS_LOG_MAX_BACKUPS" "7" # OpenIM openim-cmdutils 日志最大备份数 +def "OPENIM_CMDUTILS_LOG_MAX_AGE" "7" # OpenIM openim-cmdutils 日志最大保存时间(天) +def "OPENIM_CMDUTILS_LOG_COMPRESS" "false" # OpenIM openim-cmdutils 日志是否压缩 +def "OPENIM_CMDUTILS_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-cmdutils 日志是否带有堆栈信息 + +###################### OpenIM openim-crontask ###################### +def "OPENIM_CRONTASK_HOST" "127.0.0.1" +def "OPENIM_CRONTASK_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-crontask" # OpenIM openim-crontask 二进制文件路径 +def "OPENIM_CRONTASK_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-crontask 配置文件路径 +def "OPENIM_CRONTASK_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-crontask" # OpenIM openim-crontask 日志存储路径 +def "OPENIM_CRONTASK_LOG_LEVEL" "info" # OpenIM openim-crontask 日志级别 +def "OPENIM_CRONTASK_LOG_MAX_SIZE" "100" # OpenIM openim-crontask 日志最大大小(MB) +def "OPENIM_CRONTASK_LOG_MAX_BACKUPS" "7" # OpenIM openim-crontask 日志最大备份数 +def "OPENIM_CRONTASK_LOG_MAX_AGE" "7" # OpenIM openim-crontask 日志最大保存时间(天) +def "OPENIM_CRONTASK_LOG_COMPRESS" "false" # OpenIM openim-crontask 日志是否压缩 +def "OPENIM_CRONTASK_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-crontask 日志是否带有堆栈信息 + +###################### OpenIM openim-msggateway ###################### +def "OPENIM_MSGGATEWAY_HOST" "127.0.0.1" +def "OPENIM_MSGGATEWAY_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-msggateway" +def "OPENIM_MSGGATEWAY_CONFIG" "${OPENIM_ROOT}/config/" +def "OPENIM_MSGGATEWAY_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-msggateway" +def "OPENIM_MSGGATEWAY_LOG_LEVEL" "info" +def "OPENIM_MSGGATEWAY_LOG_MAX_SIZE" "100" +def "OPENIM_MSGGATEWAY_LOG_MAX_BACKUPS" "7" +def "OPENIM_MSGGATEWAY_LOG_MAX_AGE" "7" +def "OPENIM_MSGGATEWAY_LOG_COMPRESS" "false" +def "OPENIM_MSGGATEWAY_LOG_WITH_STACK" "${LOG_WITH_STACK}" + +# 定义 openim-msggateway 的数量, 默认为 4 +readonly OPENIM_MSGGATEWAY_NUM=${OPENIM_MSGGATEWAY_NUM:-'4'} + +###################### OpenIM openim-msgtransfer ###################### +def "OPENIM_MSGTRANSFER_HOST" "127.0.0.1" +def "OPENIM_MSGTRANSFER_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-msgtransfer" # OpenIM openim-msgtransfer 二进制文件路径 +def "OPENIM_MSGTRANSFER_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-msgtransfer 配置文件路径 +def "OPENIM_MSGTRANSFER_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-msgtransfer" # OpenIM openim-msgtransfer 日志存储路径 +def "OPENIM_MSGTRANSFER_LOG_LEVEL" "info" # OpenIM openim-msgtransfer 日志级别 +def "OPENIM_MSGTRANSFER_LOG_MAX_SIZE" "100" # OpenIM openim-msgtransfer 日志最大大小(MB) +def "OPENIM_MSGTRANSFER_LOG_MAX_BACKUPS" "7" # OpenIM openim-msgtransfer 日志最大备份数 +def "OPENIM_MSGTRANSFER_LOG_MAX_AGE" "7" # OpenIM openim-msgtransfer 日志最大保存时间(天) +def "OPENIM_MSGTRANSFER_LOG_COMPRESS" "false" # OpenIM openim-msgtransfer 日志是否压缩 +def "OPENIM_MSGTRANSFER_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-msgtransfer 日志是否带有堆栈信息 + +###################### OpenIM openim-push ###################### +def "OPENIM_PUSH_HOST" "127.0.0.1" +def "OPENIM_PUSH_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-push" # OpenIM openim-push 二进制文件路径 +def "OPENIM_PUSH_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-push 配置文件路径 +def "OPENIM_PUSH_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-push" # OpenIM openim-push 日志存储路径 +def "OPENIM_PUSH_LOG_LEVEL" "info" # OpenIM openim-push 日志级别 +def "OPENIM_PUSH_LOG_MAX_SIZE" "100" # OpenIM openim-push 日志最大大小(MB) +def "OPENIM_PUSH_LOG_MAX_BACKUPS" "7" # OpenIM openim-push 日志最大备份数 +def "OPENIM_PUSH_LOG_MAX_AGE" "7" # OpenIM openim-push 日志最大保存时间(天) +def "OPENIM_PUSH_LOG_COMPRESS" "false" # OpenIM openim-push 日志是否压缩 +def "OPENIM_PUSH_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-push 日志是否带有堆栈信息 + +###################### OpenIM openim-rpc-auth ###################### +def "OPENIM_RPC_AUTH_HOST" "127.0.0.1" +def "OPENIM_RPC_AUTH_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-auth" # OpenIM openim-rpc-auth 二进制文件路径 +def "OPENIM_RPC_AUTH_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-auth 配置文件路径 +def "OPENIM_RPC_AUTH_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-auth" # OpenIM openim-rpc-auth 日志存储路径 +def "OPENIM_RPC_AUTH_LOG_LEVEL" "info" # OpenIM openim-rpc-auth 日志级别 +def "OPENIM_RPC_AUTH_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-auth 日志最大大小(MB) +def "OPENIM_RPC_AUTH_LOG_MAX_BACKUPS" "7" # OpenIM openim-rpc-auth 日志最大备份数 +def "OPENIM_RPC_AUTH_LOG_MAX_AGE" "7" # OpenIM openim-rpc-auth 日志最大保存时间(天) +def "OPENIM_RPC_AUTH_LOG_COMPRESS" "false" # OpenIM openim-rpc-auth 日志是否压缩 +def "OPENIM_RPC_AUTH_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-rpc-auth 日志是否带有堆栈信息 + +###################### OpenIM openim-rpc-conversation ###################### +def "OPENIM_RPC_CONVERSATION_HOST" "127.0.0.1" +def "OPENIM_RPC_CONVERSATION_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-conversation" # OpenIM openim-rpc-conversation 二进制文件路径 +def "OPENIM_RPC_CONVERSATION_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-conversation 配置文件路径 +def "OPENIM_RPC_CONVERSATION_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-conversation" # OpenIM openim-rpc-conversation 日志存储路径 +def "OPENIM_RPC_CONVERSATION_LOG_LEVEL" "info" # OpenIM openim-rpc-conversation 日志级别 +def "OPENIM_RPC_CONVERSATION_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-conversation 日志最大大小(MB) +def "OPENIM_RPC_CONVERSATION_LOG_MAX_BACKUPS" "7" # OpenIM openim-rpc-conversation 日志最大备份数 +def "OPENIM_RPC_CONVERSATION_LOG_MAX_AGE" "7" # OpenIM openim-rpc-conversation 日志最大保存时间(天) +def "OPENIM_RPC_CONVERSATION_LOG_COMPRESS" "false" # OpenIM openim-rpc-conversation 日志是否压缩 +def "OPENIM_RPC_CONVERSATION_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-rpc-conversation 日志是否带有堆栈信息 + +###################### OpenIM openim-rpc-friend ###################### +def "OPENIM_RPC_FRIEND_HOST" "127.0.0.1" +def "OPENIM_RPC_FRIEND_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-friend" # OpenIM openim-rpc-friend 二进制文件路径 +def "OPENIM_RPC_FRIEND_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-friend 配置文件路径 +def "OPENIM_RPC_FRIEND_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-friend" # OpenIM openim-rpc-friend 日志存储路径 +def "OPENIM_RPC_FRIEND_LOG_LEVEL" "info" # OpenIM openim-rpc-friend 日志级别 +def "OPENIM_RPC_FRIEND_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-friend 日志最大大小(MB) +def "OPENIM_RPC_FRIEND_LOG_MAX_BACKUPS" "7" # OpenIM openim-rpc-friend 日志最大备份数 +def "OPENIM_RPC_FRIEND_LOG_MAX_AGE" "7" # OpenIM openim-rpc-friend 日志最大保存时间(天) +def "OPENIM_RPC_FRIEND_LOG_COMPRESS" "false" # OpenIM openim-rpc-friend 日志是否压缩 +def "OPENIM_RPC_FRIEND_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-rpc-friend 日志是否带有堆栈信息 + +###################### OpenIM openim-rpc-group ###################### +def "OPENIM_RPC_GROUP_HOST" "127.0.0.1" +def "OPENIM_RPC_GROUP_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-group" # OpenIM openim-rpc-group 二进制文件路径 +def "OPENIM_RPC_GROUP_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-group 配置文件路径 +def "OPENIM_RPC_GROUP_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-group" # OpenIM openim-rpc-group 日志存储路径 +def "OPENIM_RPC_GROUP_LOG_LEVEL" "info" # OpenIM openim-rpc-group 日志级别 +def "OPENIM_RPC_GROUP_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-group 日志最大大小(MB) +def "OPENIM_RPC_GROUP_LOG_MAX_BACKUPS" "7" # OpenIM openim-rpc-group 日志最大备份数 +def "OPENIM_RPC_GROUP_LOG_MAX_AGE" "7" # OpenIM openim-rpc-group 日志最大保存时间(天) +def "OPENIM_RPC_GROUP_LOG_COMPRESS" "false" # OpenIM openim-rpc-group 日志是否压缩 +def "OPENIM_RPC_GROUP_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-rpc-group 日志是否带有堆栈信息 + +###################### OpenIM openim-rpc-msg ###################### +def "OPENIM_RPC_MSG_HOST" "127.0.0.1" +def "OPENIM_RPC_MSG_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-msg" # OpenIM openim-rpc-msg 二进制文件路径 +def "OPENIM_RPC_MSG_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-msg 配置文件路径 +def "OPENIM_RPC_MSG_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-msg" # OpenIM openim-rpc-msg 日志存储路径 +def "OPENIM_RPC_MSG_LOG_LEVEL" "info" # OpenIM openim-rpc-msg 日志级别 +def "OPENIM_RPC_MSG_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-msg 日志最大大小(MB) +def "OPENIM_RPC_MSG_LOG_MAX_BACKUPS" "7" # OpenIM openim-rpc-msg 日志最大备份数 +def "OPENIM_RPC_MSG_LOG_MAX_AGE" "7" # OpenIM openim-rpc-msg 日志最大保存时间(天) +def "OPENIM_RPC_MSG_LOG_COMPRESS" "false" # OpenIM openim-rpc-msg 日志是否压缩 +def "OPENIM_RPC_MSG_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-rpc-msg 日志是否带有堆栈信息 + +###################### OpenIM openim-rpc-third ###################### +def "OPENIM_RPC_THIRD_HOST" "127.0.0.1" +def "OPENIM_RPC_THIRD_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-third" # OpenIM openim-rpc-third 二进制文件路径 +def "OPENIM_RPC_THIRD_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-third 配置文件路径 +def "OPENIM_RPC_THIRD_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-third" # OpenIM openim-rpc-third 日志存储路径 +def "OPENIM_RPC_THIRD_LOG_LEVEL" "info" # OpenIM openim-rpc-third 日志级别 +def "OPENIM_RPC_THIRD_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-third 日志最大大小(MB) +def "OPENIM_RPC_THIRD_LOG_MAX_BACKUPS" "7" # OpenIM openim-rpc-third 日志最大备份数 +def "OPENIM_RPC_THIRD_LOG_MAX_AGE" "7" # OpenIM openim-rpc-third 日志最大保存时间(天) +def "OPENIM_RPC_THIRD_LOG_COMPRESS" "false" # OpenIM openim-rpc-third 日志是否压缩 +def "OPENIM_RPC_THIRD_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-rpc-third 日志是否带有堆栈信息 + +###################### OpenIM openim-rpc-user ###################### +def "OPENIM_RPC_USER_HOST" "127.0.0.1" +def "OPENIM_RPC_USER_BINARY" "${OPENIM_OUTPUT_HOSTBIN}/openim-rpc-user" # OpenIM openim-rpc-user 二进制文件路径 +def "OPENIM_RPC_USER_CONFIG" "${OPENIM_ROOT}/config/" # OpenIM openim-rpc-user 配置文件路径 +def "OPENIM_RPC_USER_LOG_DIR" "${LOG_STORAGE_LOCATION}/openim-rpc-user" # OpenIM openim-rpc-user 日志存储路径 +def "OPENIM_RPC_USER_LOG_LEVEL" "info" # OpenIM openim-rpc-user 日志级别 +def "OPENIM_RPC_USER_LOG_MAX_SIZE" "100" # OpenIM openim-rpc-user 日志最大大小(MB) +def "OPENIM_RPC_USER_LOG_MAX_BACKUPS" "7" # OpenIM openim-rpc-user 日志最大备份数 +def "OPENIM_RPC_USER_LOG_MAX_AGE" "7" # OpenIM openim-rpc-user 日志最大保存时间(天) +def "OPENIM_RPC_USER_LOG_COMPRESS" "false" # OpenIM openim-rpc-user 日志是否压缩 +def "OPENIM_RPC_USER_LOG_WITH_STACK" "${LOG_WITH_STACK}" # OpenIM openim-rpc-user 日志是否带有堆栈信息 + +###################### 设计中...暂时不需要###################### + +# openimctl 配置 +def "CONFIG_USER_USERNAME" "admin" +def "CONFIG_USER_PASSWORD" "Admin@2021" +def "CONFIG_USER_CLIENT_CERTIFICATE" "${HOME}/.openim/cert/admin.pem" +def "CONFIG_USER_CLIENT_KEY" "${HOME}/.openim/cert/admin-key.pem" +def "CONFIG_SERVER_ADDRESS" "${OPENIM_APISERVER_HOST}:${OPENIM_APISERVER_SECURE_BIND_PORT}" +def "CONFIG_SERVER_CERTIFICATE_AUTHORITY" "${CA_FILE}" diff --git a/scripts/install/install-protobuf.sh b/scripts/install/install-protobuf.sh new file mode 100755 index 000000000..c75dc7e25 --- /dev/null +++ b/scripts/install/install-protobuf.sh @@ -0,0 +1,116 @@ +#!/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 Protoc Tool v1.0.0 +# -------------------------------------------------------------- +# OpenIM has released its custom Protoc tool version v1.0.0. +# This tool is customized to meet the specific needs of OpenIM and resides in its separate repository. +# It can be downloaded from the following link: +# https://github.com/OpenIMSDK/Open-IM-Protoc/releases/tag/v1.0.0 +# +# Download link (Windows): https://github.com/OpenIMSDK/Open-IM-Protoc/releases/download/v1.0.0/windows.zip +# Download link (Linux): https://github.com/OpenIMSDK/Open-IM-Protoc/releases/download/v1.0.0/linux.zip +# +# Installation steps (taking Windows as an example): +# 1. Visit the above link and download the version suitable for Windows. +# 2. Extract the downloaded file. +# 3. Add the extracted tool to your PATH environment variable so that it can be run directly from the command line. +# +# Note: The specific installation and usage instructions may vary based on the tool's actual implementation. It's advised to refer to official documentation. +# -------------------------------------------------------------- + +PROTOC_DOWNLOAD_URL="https://github.com/OpenIMSDK/Open-IM-Protoc/releases/download/v1.0.0/linux.zip" +DOWNLOAD_DIR="/tmp/openim-protoc" +INSTALL_DIR="/usr/local/bin" + +function help_message { + echo "Usage: ./install-protobuf.sh [option]" + echo "Options:" + echo "-i, --install Install the OpenIM Protoc tool." + echo "-u, --uninstall Uninstall the OpenIM Protoc tool." + echo "-r, --reinstall Reinstall the OpenIM Protoc tool." + echo "-c, --check Check if the OpenIM Protoc tool is installed." + echo "-h, --help Display this help message." +} + +function install_protobuf { + echo "Installing OpenIM Protoc tool..." + + # Create temporary directory and download the zip file + mkdir -p $DOWNLOAD_DIR + wget $PROTOC_DOWNLOAD_URL -O $DOWNLOAD_DIR/linux.zip + + # Unzip the file + unzip -o $DOWNLOAD_DIR/linux.zip -d $DOWNLOAD_DIR + + # Move binaries to the install directory and make them executable + sudo cp $DOWNLOAD_DIR/linux/protoc $INSTALL_DIR/ + sudo cp $DOWNLOAD_DIR/linux/protoc-gen-go $INSTALL_DIR/ + sudo chmod +x $INSTALL_DIR/protoc + sudo chmod +x $INSTALL_DIR/protoc-gen-go + + # Clean up + rm -rf $DOWNLOAD_DIR + + echo "OpenIM Protoc tool installed successfully!" +} + +function uninstall_protobuf { + echo "Uninstalling OpenIM Protoc tool..." + + # Removing binaries from the install directory + sudo rm -f $INSTALL_DIR/protoc + sudo rm -f $INSTALL_DIR/protoc-gen-go + + echo "OpenIM Protoc tool uninstalled successfully!" +} + +function reinstall_protobuf { + echo "Reinstalling OpenIM Protoc tool..." + uninstall_protobuf + install_protobuf +} + +function check_protobuf { + echo "Checking for OpenIM Protoc tool installation..." + + which protoc > /dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "OpenIM Protoc tool is installed." + else + echo "OpenIM Protoc tool is not installed." + fi +} + +while [ "$1" != "" ]; do + case $1 in + -i | --install ) install_protobuf + ;; + -u | --uninstall ) uninstall_protobuf + ;; + -r | --reinstall ) reinstall_protobuf + ;; + -c | --check ) check_protobuf + ;; + -h | --help ) help_message + exit + ;; + * ) help_message + exit 1 + esac + shift +done diff --git a/scripts/install/install.sh b/scripts/install/install.sh new file mode 100755 index 000000000..6c891d4f2 --- /dev/null +++ b/scripts/install/install.sh @@ -0,0 +1,149 @@ +#!/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 Server Installation Script +# +# Description: +# This script is designed to handle the installation, Is a deployment solution +# that uses the Linux systen extension. uninstallation, and +# status checking of OpenIM components on the server. OpenIM is a presumed +# communication or messaging platform based on the context. +# +# Usage: +# To utilize this script, you need to invoke it with specific commands +# and options as detailed below. +# +# Commands: +# -i, --install : Use this command to initiate the installation of all +# OpenIM components. +# -u, --uninstall : Use this command to uninstall or remove all +# OpenIM components from the server. +# -s, --status : This command can be used to check and report the +# current operational status of the installed OpenIM components. +# -h, --help : For any assistance or to view the available commands, +# use this command to display the help menu. +# +# Example Usage: +# To install all OpenIM components: +# ./scripts/install/install.sh -i +# or +# ./scripts/install/install.sh --install +# +# Note: +# Ensure you have the necessary privileges to execute installation or +# uninstallation operations. It's generally recommended to take a backup +# before making major changes. +# +############################################################################### + +OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P) +[[ -z ${COMMON_SOURCED} ]] && source ${OPENIM_ROOT}/scripts/install/common.sh + +source ${OPENIM_ROOT}/scripts/install/openim-msggateway.sh +source ${OPENIM_ROOT}/scripts/install/openim-msgtransfer.sh +source ${OPENIM_ROOT}/scripts/install/openim-push.sh +source ${OPENIM_ROOT}/scripts/install/openim-rpc.sh +source ${OPENIM_ROOT}/scripts/install/openim-crontask.sh +source ${OPENIM_ROOT}/scripts/install/openim-api.sh +source ${OPENIM_ROOT}/scripts/install/openim-man.sh +source ${OPENIM_ROOT}/scripts/install/openim-tools.sh +source ${OPENIM_ROOT}/scripts/install/test.sh + +# Detailed help function +function openim::install::show_help() { + echo "OpenIM Installer" + echo "Usage: $0 [options]" + echo "" + echo "Commands:" + echo " -i, --install Install all OpenIM components." + echo " -u, --uninstall Remove all OpenIM components." + echo " -s, --status Check the current status of OpenIM components." + echo " -h, --help Show this help menu." + echo "" + echo "Example: " + echo " $0 -i Will install all OpenIM components." + echo " $0 --install Same as above." +} + +function openim::install::install_openim() +{ + openim::log::info "check openim dependency" + openim::util::check_ports ${OPENIM_DEPENDENCY_PORT_LISTARIES[@]} + + openim::msggateway::install || return 1 + openim::msgtransfer::install || return 1 + openim::push::install || return 1 + openim::rpc::install || return 1 + openim::crontask::install || return 1 + openim::api::install || return 1 + + openim::log::success "openim install success" +} + +function openim::uninstall::uninstall_openim() +{ + openim::log::info "uninstall openim" + + openim::msggateway::uninstall || return 1 + openim::msgtransfer::uninstall || return 1 + openim::push::uninstall || return 1 + openim::rpc::uninstall || return 1 + openim::crontask::uninstall || return 1 + openim::api::uninstall || return 1 + + openim::log::success "openim uninstall success" +} + +function openim::install::status() +{ + openim::log::info "check openim status" + + openim::msggateway::status || return 1 + openim::msgtransfer::status || return 1 + openim::push::status || return 1 + openim::rpc::status || return 1 + openim::crontask::status || return 1 + openim::api::status || return 1 + + openim::log::success "openim status success" +} + +# If no arguments are provided, show help +if [[ $# -eq 0 ]]; then + openim::install::show_help + exit 0 +fi + +# Argument parsing to call functions based on user input +while (( "$#" )); do + case "$1" in + -i|--install) + openim::install::install_openim + shift + ;; + -u|--uninstall) + openim::uninstall::uninstall_openim + shift + ;; + -s|--status) + openim::install::status + shift + ;; + -h|--help|*) + openim::install::show_help + exit 0 + ;; + esac +done \ No newline at end of file diff --git a/scripts/install/openim-api.sh b/scripts/install/openim-api.sh new file mode 100755 index 000000000..b7cd1da7b --- /dev/null +++ b/scripts/install/openim-api.sh @@ -0,0 +1,112 @@ +#!/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 -o errexit +set +o nounset +set -o pipefail + +OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P) +[[ -z ${COMMON_SOURCED} ]] && source ${OPENIM_ROOT}/scripts/install/common.sh + +SERVER_NAME="openim-api" + +readonly OPENIM_API_PORT_TARGETS=( + ${API_OPENIM_PORT} +) +readonly OPENIM_API_PORT_LISTARIES=("${OPENIM_API_PORT_TARGETS[@]##*/}") + +readonly OPENIM_API_SERVICE_TARGETS=( + openim-api +) +readonly OPENIM_API_SERVICE_LISTARIES=("${OPENIM_API_SERVICE_TARGETS[@]##*/}") + +function openim::api::start() +{ + echo "++ OPENIM_API_SERVICE_LISTARIES: ${OPENIM_API_SERVICE_LISTARIES[@]}" + echo "++ OPENIM_API_PORT_LISTARIES: ${OPENIM_API_PORT_LISTARIES[@]}" + echo "++ OpenIM API config path: ${OPENIM_API_CONFIG}" + + openim::log::info "Starting ${SERVER_NAME} ..." + + printf "+------------------------+--------------+\n" + printf "| Service Name | Port |\n" + printf "+------------------------+--------------+\n" + + length=${#OPENIM_API_SERVICE_LISTARIES[@]} + + for ((i=0; i<$length; i++)); do + printf "| %-22s | %6s |\n" "${OPENIM_API_SERVICE_LISTARIES[$i]}" "${OPENIM_API_PORT_LISTARIES[$i]}" + printf "+------------------------+--------------+\n" + done + # start all api services + for ((i = 0; i < ${#OPENIM_API_SERVICE_LISTARIES[*]}; i++)); do + openim::util::stop_services_with_name ${OPENIM_API_SERVICE_LISTARIES[$i]} + openim::log::info "OpenIM ${OPENIM_API_SERVICE_LISTARIES[$i]} config path: ${OPENIM_API_CONFIG}" + + # Get the service and Prometheus ports. + OPENIM_API_SERVICE_PORTS=( $(openim::util::list-to-string ${OPENIM_API_PORT_LISTARIES[$i]}) ) + + # TODO Only one port is supported. An error occurs on multiple ports + if [ ${#OPENIM_API_SERVICE_PORTS[@]} -ne 1 ]; then + openim::log::error_exit "Set only one port for ${OPENIM_API_SERVICE_LISTARIES[$i]} service." + fi + + for ((j = 0; j < ${#OPENIM_API_SERVICE_PORTS[@]}; j++)); do + openim::log::info "Starting ${OPENIM_API_SERVICE_LISTARIES[$i]} service, port: ${OPENIM_API_SERVICE_PORTS[j]}, binary root: ${OPENIM_OUTPUT_HOSTBIN}/${OPENIM_API_SERVICE_LISTARIES[$i]}" + openim::api::start_service "${OPENIM_API_SERVICE_LISTARIES[$i]}" "${OPENIM_API_PORT_LISTARIES[j]}" + sleep 1 + done + done + + OPENIM_API_PORT_STRINGARIES=( $(openim::util::list-to-string ${OPENIM_API_PORT_LISTARIES[@]}) ) + openim::util::check_ports ${OPENIM_API_PORT_STRINGARIES[@]} +} + +function openim::api::start_service() { + local binary_name="$1" + local service_port="$2" + local prometheus_port="$3" + + local cmd="${OPENIM_OUTPUT_HOSTBIN}/${binary_name} --port ${service_port} -c ${OPENIM_API_CONFIG}" + + nohup ${cmd} >> "${LOG_FILE}" 2>&1 & + + if [ $? -ne 0 ]; then + openim::log::error_exit "Failed to start ${binary_name} on port ${service_port}." + fi +} + +###################################### Linux Systemd ###################################### +SYSTEM_FILE_PATH="/etc/systemd/system/${SERVER_NAME}.service" + +function openim::api::install() { + openim::log::info "Installing ${SERVER_NAME} ..." +} + +function openim::api::uninstall() { + openim::log::info "Uninstalling ${SERVER_NAME} ..." + +} + +function openim::api::status() { + openim::log::info "Checking ${SERVER_NAME} status ..." + + openim::util::check_ports ${OPENIM_API_PORT_LISTARIES[@]} +} + +if [[ "$*" =~ openim::api:: ]];then + eval $* +fi \ No newline at end of file diff --git a/scripts/install/openim-crontask.sh b/scripts/install/openim-crontask.sh new file mode 100755 index 000000000..674c0ee39 --- /dev/null +++ b/scripts/install/openim-crontask.sh @@ -0,0 +1,132 @@ +#!/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 CronTask Control Script +# +# Description: +# This script provides a control interface for the OpenIM CronTask service within a Linux environment. It supports two installation methods: installation via function calls to systemctl, and direct installation through background processes. +# +# Features: +# 1. Robust error handling leveraging Bash built-ins such as 'errexit', 'nounset', and 'pipefail'. +# 2. Capability to source common utility functions and configurations, ensuring environmental consistency. +# 3. Comprehensive logging tools, offering clear operational insights. +# 4. Support for creating, managing, and interacting with Linux systemd services. +# 5. Mechanisms to verify the successful running of the service. +# +# Usage: +# 1. Direct Script Execution: +# This will start the OpenIM CronTask directly through a background process. +# Example: ./openim-crontask.sh openim::crontask::start +# +# 2. Controlling through Functions for systemctl operations: +# Specific operations like installation, uninstallation, and status check can be executed by passing the respective function name as an argument to the script. +# Example: ./openim-crontask.sh openim::crontask::install +# +# Note: Ensure that the appropriate permissions and environmental variables are set prior to script execution. +# + +OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P) +[[ -z ${COMMON_SOURCED} ]] && source ${OPENIM_ROOT}/scripts/install/common.sh + +SERVER_NAME="openim-crontask" + +function openim::crontask::start() +{ + openim::log::info "Start OpenIM Cron, binary root: ${SERVER_NAME}" + openim::log::status "Start OpenIM Cron, path: ${OPENIM_CRONTASK_BINARY}" + + openim::util::stop_services_with_name ${SERVER_NAME} + + openim::log::status "start cron_task process, path: ${OPENIM_CRONTASK_BINARY}" + nohup ${OPENIM_CRONTASK_BINARY} >> ${LOG_FILE} 2>&1 & + openim::util::check_process_names ${SERVER_NAME} +} + +###################################### Linux Systemd ###################################### +SYSTEM_FILE_PATH="/etc/systemd/system/${SERVER_NAME}.service" + +# Print the necessary information after installation +function openim::crontask::info() { +cat << EOF +openim-crontask listen on: ${OPENIM_CRONTASK_HOST} +EOF +} + +# install openim-crontask +function openim::crontask::install() +{ + pushd ${OPENIM_ROOT} + + # 1. Build openim-crontask + make build BINS=${SERVER_NAME} + openim::common::sudo "cp ${OPENIM_OUTPUT_HOSTBIN}/${SERVER_NAME} ${OPENIM_INSTALL_DIR}/bin" + + openim::log::status "${SERVER_NAME} binary: ${OPENIM_INSTALL_DIR}/bin/${SERVER_NAME}" + + # 2. Generate and install the openim-crontask configuration file (openim-crontask.yaml) + echo ${LINUX_PASSWORD} | sudo -S bash -c \ + "./scripts/genconfig.sh ${ENV_FILE} deployments/templates/${SERVER_NAME}.yaml > ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml" + openim::log::status "${SERVER_NAME} config file: ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml" + + # 3. Create and install the ${SERVER_NAME} systemd unit file + echo ${LINUX_PASSWORD} | sudo -S bash -c \ + "./scripts/genconfig.sh ${ENV_FILE} deployments/templates/init/${SERVER_NAME}.service > ${SYSTEM_FILE_PATH}" + openim::log::status "${SERVER_NAME} systemd file: ${SYSTEM_FILE_PATH}" + + # 4. Start the openim-crontask service + openim::common::sudo "systemctl daemon-reload" + openim::common::sudo "systemctl restart ${SERVER_NAME}" + openim::common::sudo "systemctl enable ${SERVER_NAME}" + openim::crontask::status || return 1 + openim::crontask::info + + openim::log::info "install ${SERVER_NAME} successfully" + popd +} + + +# Unload +function openim::crontask::uninstall() +{ + set +o errexit + openim::common::sudo "systemctl stop ${SERVER_NAME}" + openim::common::sudo "systemctl disable ${SERVER_NAME}" + openim::common::sudo "rm -f ${OPENIM_INSTALL_DIR}/bin/${SERVER_NAME}" + openim::common::sudo "rm -f ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml" + openim::common::sudo "rm -f /etc/systemd/system/${SERVER_NAME}.service" + set -o errexit + openim::log::info "uninstall ${SERVER_NAME} successfully" +} + +# Status Check +function openim::crontask::status() +{ + # Check the running status of the ${SERVER_NAME}. If active (running) is displayed, the ${SERVER_NAME} is started successfully. + systemctl status ${SERVER_NAME}|grep -q 'active' || { + openim::log::error "${SERVER_NAME} failed to start, maybe not installed properly" + return 1 + } + + # The listening port is hardcode in the configuration file + if echo | telnet 127.0.0.1 7070 2>&1|grep refused &>/dev/null;then + openim::log::error "cannot access health check port, ${SERVER_NAME} maybe not startup" + return 1 + fi +} + +if [[ "$*" =~ openim::crontask:: ]];then + eval $* +fi diff --git a/scripts/install/openim-man.sh b/scripts/install/openim-man.sh new file mode 100755 index 000000000..96d94ab8b --- /dev/null +++ b/scripts/install/openim-man.sh @@ -0,0 +1,96 @@ +#!/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-man.sh Script to manage man pages for openim +# +# Description: +# This script manages the man pages for the OpenIM software suite. +# It provides facilities to install, uninstall, and verify the +# installation status of the man pages related to OpenIM components. +# +# Usage: +# ./openim-man.sh openim::man::install - Install man pages +# ./openim-man.sh openim::man::uninstall - Uninstall man pages +# ./openim-man.sh openim::man::status - Check installation status +# +# Dependencies: +# - Assumes there's a common.sh in "${OPENIM_ROOT}/scripts/install/" +# containing shared functions and variables. +# - Relies on the script "${OPENIM_ROOT}/scripts/update-generated-docs.sh" +# to generate the man pages. +# +# Notes: +# - This script must be run with appropriate permissions to modify the +# system man directories. +# - Always ensure you're in the script's directory or provide the correct +# path when executing. +################################################################################ + +# Define the root of the build/dist directory +OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd) + +# Ensure the common script is sourced +[[ -z ${COMMON_SOURCED} ]] && source "${OPENIM_ROOT}/scripts/install/common.sh" + +# Print usage information after installation +function openim::man::info() { +cat <<- EOF +Usage: + man openim-server # Display the man page for openim-server +EOF +} + +# Install the man pages for openim +function openim::man::install() { + # Navigate to the openim root directory + pushd "${OPENIM_ROOT}" > /dev/null + + # Generate man pages for each component + "${OPENIM_ROOT}/scripts/update-generated-docs.sh" + openim::common::sudo "cp docs/man/man1/* /usr/share/man/man1/" + + # Verify installation status + if openim::man::status; then + openim::log::info "Installed openim-server man page successfully" + openim::man::info + fi + + # Return to the original directory + popd > /dev/null +} + +# Uninstall the man pages for openim +function openim::man::uninstall() { + # Turn off exit-on-error temporarily to handle non-existing files gracefully + set +o errexit + openim::common::sudo "rm -f /usr/share/man/man1/openim-*" + set -o errexit + + openim::log::info "Uninstalled openim man pages successfully" +} + +# Check the installation status of the man pages +function openim::man::status() { + if ! ls /usr/share/man/man1/openim-* &> /dev/null; then + openim::log::error "OpenIM man files not found. Perhaps they were not installed correctly." + return 1 + fi + return 0 +} + +# Execute the appropriate function based on the given arguments +if [[ "$*" =~ openim::man:: ]]; then + eval "$*" +fi diff --git a/scripts/install/openim-msggateway.sh b/scripts/install/openim-msggateway.sh new file mode 100755 index 000000000..6adac9dc1 --- /dev/null +++ b/scripts/install/openim-msggateway.sh @@ -0,0 +1,141 @@ +#!/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. + +# Common utilities, variables and checks for all build scripts. +set -o errexit +set +o nounset +set -o pipefail + +ulimit -n 200000 + +OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P) +[[ -z ${COMMON_SOURCED} ]] && source ${OPENIM_ROOT}/scripts/install/common.sh + +SERVER_NAME="openim-msggateway" + +function openim::msggateway::start() +{ + openim::log::info "Start OpenIM Msggateway, binary root: ${SERVER_NAME}" + openim::log::status "Start OpenIM Msggateway, path: ${OPENIM_MSGGATEWAY_BINARY}" + + openim::util::stop_services_with_name ${SERVER_NAME} + + # OpenIM message gateway service port + OPENIM_RPC_PORTS=$(openim::util::list-to-string ${OPENIM_MESSAGE_GATEWAY_PORT} ) + # OpenIM WS port + OPENIM_WS_PORTS=$(openim::util::list-to-string ${OPENIM_WS_PORT} ) + # Message Gateway Prometheus port of the service + MSG_GATEWAY_PROM_PORTS=$(openim::util::list-to-string ${MSG_GATEWAY_PROM_PORT} ) + + openim::log::status "OpenIM RPC ports: ${OPENIM_RPC_PORTS[*]}" + openim::log::status "OpenIM WS ports: ${OPENIM_WS_PORTS[*]}" + openim::log::status "OpenIM Prometheus ports: ${MSG_GATEWAY_PROM_PORTS[*]}" + + openim::log::status "OpenIM Msggateway config path: ${OPENIM_MSGGATEWAY_CONFIG}" + + if [ ${#OPENIM_RPC_PORTS[@]} -ne ${#OPENIM_WS_PORTS[@]} ]; then + openim::log::error "ws_ports does not match push_rpc_ports or prome_ports in quantity!!!" + exit 1 + fi + + for ((i = 0; i < ${#OPENIM_WS_PORTS[@]}; i++)); do + openim::log::info "start push process, port: ${OPENIM_MSGGATEWAY_PORTS_ARRAY[$i]}, prometheus port: ${PUSH_MSGGATEWAY_PORTS_ARRAY[$i]}" + + PROMETHEUS_PORT_OPTION="" + if [[ -n "${MSG_GATEWAY_PROM_PORTS[$i]}" ]]; then + PROMETHEUS_PORT_OPTION="--prometheus_port ${MSG_GATEWAY_PROM_PORTS[$i]}" + fi + + nohup ${OPENIM_MSGGATEWAY_BINARY} --port ${OPENIM_RPC_PORTS[$i]} --ws_port ${OPENIM_WS_PORTS[$i]} $PROMETHEUS_PORT_OPTION -c ${OPENIM_MSGGATEWAY_CONFIG} >> ${LOG_FILE} 2>&1 & + done + + openim::util::check_process_names ${SERVER_NAME} +} + +###################################### Linux Systemd ###################################### +SYSTEM_FILE_PATH="/etc/systemd/system/${SERVER_NAME}.service" + +# Print the necessary information after installation +function openim::msggateway::info() { +cat << EOF +openim-msggateway listen on: ${OPENIM_MSGGATEWAY_HOST} +EOF +} + +# install openim-msggateway +function openim::msggateway::install() +{ + pushd ${OPENIM_ROOT} + + # 1. Build openim-msggateway + make build BINS=${SERVER_NAME} + openim::common::sudo "cp ${OPENIM_OUTPUT_HOSTBIN}/${SERVER_NAME} ${OPENIM_INSTALL_DIR}/bin" + + openim::log::status "${SERVER_NAME} binary: ${OPENIM_INSTALL_DIR}/bin/${SERVER_NAME}" + + # 2. Generate and install the openim-msggateway configuration file (openim-msggateway.yaml) + echo ${LINUX_PASSWORD} | sudo -S bash -c \ + "./scripts/genconfig.sh ${ENV_FILE} deployments/templates/${SERVER_NAME}.yaml > ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml" + openim::log::status "${SERVER_NAME} config file: ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml" + + # 3. Create and install the ${SERVER_NAME} systemd unit file + echo ${LINUX_PASSWORD} | sudo -S bash -c \ + "./scripts/genconfig.sh ${ENV_FILE} deployments/templates/init/${SERVER_NAME}.service > ${SYSTEM_FILE_PATH}" + openim::log::status "${SERVER_NAME} systemd file: ${SYSTEM_FILE_PATH}" + + # 4. Start the openim-msggateway service + openim::common::sudo "systemctl daemon-reload" + openim::common::sudo "systemctl restart ${SERVER_NAME}" + openim::common::sudo "systemctl enable ${SERVER_NAME}" + openim::msggateway::status || return 1 + openim::msggateway::info + + openim::log::info "install ${SERVER_NAME} successfully" + popd +} + + +# Unload +function openim::msggateway::uninstall() +{ + set +o errexit + openim::common::sudo "systemctl stop ${SERVER_NAME}" + openim::common::sudo "systemctl disable ${SERVER_NAME}" + openim::common::sudo "rm -f ${OPENIM_INSTALL_DIR}/bin/${SERVER_NAME}" + openim::common::sudo "rm -f ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml" + openim::common::sudo "rm -f /etc/systemd/system/${SERVER_NAME}.service" + set -o errexit + openim::log::info "uninstall ${SERVER_NAME} successfully" +} + +# Status Check +function openim::msggateway::status() +{ + # Check the running status of the ${SERVER_NAME}. If active (running) is displayed, the ${SERVER_NAME} is started successfully. + systemctl status ${SERVER_NAME}|grep -q 'active' || { + openim::log::error "${SERVER_NAME} failed to start, maybe not installed properly" + return 1 + } + + # The listening port is hardcode in the configuration file + if echo | telnet 127.0.0.1 7070 2>&1|grep refused &>/dev/null;then + openim::log::error "cannot access health check port, ${SERVER_NAME} maybe not startup" + return 1 + fi +} + +if [[ "$*" =~ openim::msggateway:: ]];then + eval $* +fi diff --git a/scripts/install/openim-msgtransfer.sh b/scripts/install/openim-msgtransfer.sh new file mode 100755 index 000000000..564068c97 --- /dev/null +++ b/scripts/install/openim-msgtransfer.sh @@ -0,0 +1,155 @@ +#!/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. + +# Common utilities, variables and checks for all build scripts. +set -o errexit +set +o nounset +set -o pipefail + +ulimit -n 200000 + +OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P) +[[ -z ${COMMON_SOURCED} ]] && source ${OPENIM_ROOT}/scripts/install/common.sh + +SERVER_NAME="openim-msgtransfer" + +function openim::msgtransfer::start() +{ + openim::log::info "Start OpenIM Msggateway, binary root: ${SERVER_NAME}" + openim::log::status "Start OpenIM Msggateway, path: ${OPENIM_MSGTRANSFER_BINARY}" + + openim::util::stop_services_with_name ${SERVER_NAME} + + # Message Transfer Prometheus port list + MSG_TRANSFER_PROM_PORTS=(openim::util::list-to-string ${MSG_TRANSFER_PROM_PORT} ) + + openim::log::status "OpenIM Prometheus ports: ${MSG_TRANSFER_PROM_PORTS[*]}" + + openim::log::status "OpenIM Msggateway config path: ${OPENIM_MSGTRANSFER_CONFIG}" + + openim::log::info "openim maggateway num: ${OPENIM_MSGGATEWAY_NUM}" + + if [ "${OPENIM_MSGGATEWAY_NUM}" -lt 1 ]; then + opeim::log::error_exit "OPENIM_MSGGATEWAY_NUM must be greater than 0" + fi + + if [ ${OPENIM_MSGGATEWAY_NUM} -ne $((${#MSG_TRANSFER_PROM_PORTS[@]} - 1)) ]; then + openim::log::error_exit "OPENIM_MSGGATEWAY_NUM must be equal to the number of MSG_TRANSFER_PROM_PORTS" + fi + + for (( i=1; i<=$OPENIM_MSGGATEWAY_NUM; i++ )) do + openim::log::info "prometheus port: ${MSG_TRANSFER_PROM_PORTS[$i]}" + PROMETHEUS_PORT_OPTION="" + if [[ -n "${OPENIM_PROMETHEUS_PORTS[$i]}" ]]; then + PROMETHEUS_PORT_OPTION="--prometheus_port ${OPENIM_PROMETHEUS_PORTS[$i]}" + fi + nohup ${OPENIM_MSGTRANSFER_BINARY} ${PROMETHEUS_PORT_OPTION} -c ${OPENIM_MSGTRANSFER_CONFIG} >> ${LOG_FILE} 2>&1 & + done + + openim::util::check_process_names "${OPENIM_OUTPUT_HOSTBIN}/${SERVER_NAME}" +} + +function openim::msgtransfer::check() +{ + PIDS=$(pgrep -f "${OPENIM_OUTPUT_HOSTBIN}/openim-msgtransfer") + + NUM_PROCESSES=$(echo "$PIDS" | wc -l) + # NUM_PROCESSES=$(($NUM_PROCESSES - 1)) + + if [ "$NUM_PROCESSES" -eq "$OPENIM_MSGGATEWAY_NUM" ]; then + openim::log::info "Found $OPENIM_MSGGATEWAY_NUM processes named $OPENIM_OUTPUT_HOSTBIN" + for PID in $PIDS; do + ps -p $PID -o pid,cmd + done + else + openim::log::error_exit "Expected $OPENIM_MSGGATEWAY_NUM openim msgtransfer processes, but found $NUM_PROCESSES msgtransfer processes." + fi +} + +###################################### Linux Systemd ###################################### +SYSTEM_FILE_PATH="/etc/systemd/system/${SERVER_NAME}.service" + +# Print the necessary information after installation +function openim::msgtransfer::info() { +cat << EOF +openim-msgtransfer listen on: ${OPENIM_MSGTRANSFER_HOST} +EOF +} + +# install openim-msgtransfer +function openim::msgtransfer::install() +{ + pushd ${OPENIM_ROOT} + + # 1. Build openim-msgtransfer + make build BINS=${SERVER_NAME} + openim::common::sudo "cp ${OPENIM_OUTPUT_HOSTBIN}/${SERVER_NAME} ${OPENIM_INSTALL_DIR}/bin" + + openim::log::status "${SERVER_NAME} binary: ${OPENIM_INSTALL_DIR}/bin/${SERVER_NAME}" + + # 2. Generate and install the openim-msgtransfer configuration file (openim-msgtransfer.yaml) + echo ${LINUX_PASSWORD} | sudo -S bash -c \ + "./scripts/genconfig.sh ${ENV_FILE} deployments/templates/${SERVER_NAME}.yaml > ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml" + openim::log::status "${SERVER_NAME} config file: ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml" + + # 3. Create and install the ${SERVER_NAME} systemd unit file + echo ${LINUX_PASSWORD} | sudo -S bash -c \ + "./scripts/genconfig.sh ${ENV_FILE} deployments/templates/init/${SERVER_NAME}.service > ${SYSTEM_FILE_PATH}" + openim::log::status "${SERVER_NAME} systemd file: ${SYSTEM_FILE_PATH}" + + # 4. Start the openim-msgtransfer service + openim::common::sudo "systemctl daemon-reload" + openim::common::sudo "systemctl restart ${SERVER_NAME}" + openim::common::sudo "systemctl enable ${SERVER_NAME}" + openim::msgtransfer::status || return 1 + openim::msgtransfer::info + + openim::log::info "install ${SERVER_NAME} successfully" + popd +} + + +# Unload +function openim::msgtransfer::uninstall() +{ + set +o errexit + openim::common::sudo "systemctl stop ${SERVER_NAME}" + openim::common::sudo "systemctl disable ${SERVER_NAME}" + openim::common::sudo "rm -f ${OPENIM_INSTALL_DIR}/bin/${SERVER_NAME}" + openim::common::sudo "rm -f ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml" + openim::common::sudo "rm -f /etc/systemd/system/${SERVER_NAME}.service" + set -o errexit + openim::log::info "uninstall ${SERVER_NAME} successfully" +} + +# Status Check +function openim::msgtransfer::status() +{ + # Check the running status of the ${SERVER_NAME}. If active (running) is displayed, the ${SERVER_NAME} is started successfully. + systemctl status ${SERVER_NAME}|grep -q 'active' || { + openim::log::error "${SERVER_NAME} failed to start, maybe not installed properly" + return 1 + } + + # The listening port is hardcode in the configuration file + if echo | telnet 127.0.0.1 7070 2>&1|grep refused &>/dev/null;then + openim::log::error "cannot access health check port, ${SERVER_NAME} maybe not startup" + return 1 + fi +} + +if [[ "$*" =~ openim::msgtransfer:: ]];then + eval $* +fi diff --git a/scripts/install/openim-push.sh b/scripts/install/openim-push.sh new file mode 100755 index 000000000..3be01bfbb --- /dev/null +++ b/scripts/install/openim-push.sh @@ -0,0 +1,153 @@ +#!/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 Push Control Script +# +# Description: +# This script provides a control interface for the OpenIM Push service within a Linux environment. It supports two installation methods: installation via function calls to systemctl, and direct installation through background processes. +# +# Features: +# 1. Robust error handling leveraging Bash built-ins such as 'errexit', 'nounset', and 'pipefail'. +# 2. Capability to source common utility functions and configurations, ensuring environmental consistency. +# 3. Comprehensive logging tools, offering clear operational insights. +# 4. Support for creating, managing, and interacting with Linux systemd services. +# 5. Mechanisms to verify the successful running of the service. +# +# Usage: +# 1. Direct Script Execution: +# This will start the OpenIM push directly through a background process. +# Example: ./openim-push.sh +# +# 2. Controlling through Functions for systemctl operations: +# Specific operations like installation, uninstallation, and status check can be executed by passing the respective function name as an argument to the script. +# Example: ./openim-push.sh openim::push::install +# +# ENVIRONMENT VARIABLES: +# export OPENIM_PUSH_BINARY="8080 8081 8082" +# export OPENIM_PUSH_PORT="9090 9091 9092" +# +# Note: Ensure that the appropriate permissions and environmental variables are set prior to script execution. +# +set -o errexit +set +o nounset +set -o pipefail + +OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P) +[[ -z ${COMMON_SOURCED} ]] && source ${OPENIM_ROOT}/scripts/install/common.sh + +SERVER_NAME="openim-push" + +function openim::push::start() +{ + openim::log::status "Start OpenIM Push, binary root: ${SERVER_NAME}" + openim::log::info "Start OpenIM Push, path: ${OPENIM_PUSH_BINARY}" + + openim::util::stop_services_with_name ${SERVER_NAME} + + openim::log::status "prepare start push process, path: ${OPENIM_PUSH_BINARY}" + openim::log::status "prepare start push process, port: ${OPENIM_PUSH_PORT}, prometheus port: ${PUSH_PROM_PORT}" + + OPENIM_PUSH_PORTS_ARRAY=$(openim::util::list-to-string ${OPENIM_PUSH_PORT} ) + PUSH_PROM_PORTS_ARRAY=$(openim::util::list-to-string ${PUSH_PROM_PORT} ) + + openim::log::status "push port list: ${OPENIM_PUSH_PORTS_ARRAY[@]}" + openim::log::status "prometheus port list: ${PUSH_PROM_PORTS_ARRAY[@]}" + + if [ ${#OPENIM_PUSH_PORTS_ARRAY[@]} -ne ${#PUSH_PROM_PORTS_ARRAY[@]} ]; then + openim::log::error_exit "The length of the two port lists is different!" + fi + + for (( i=0; i<${#OPENIM_PUSH_PORTS_ARRAY[@]}; i++ )); do + openim::log::info "start push process, port: ${OPENIM_PUSH_PORTS_ARRAY[$i]}, prometheus port: ${PUSH_PROM_PORTS_ARRAY[$i]}" + nohup ${OPENIM_PUSH_BINARY} --port ${OPENIM_PUSH_PORTS_ARRAY[$i]} --prometheus_port ${PUSH_PROM_PORTS_ARRAY[$i]} >> ${LOG_FILE} 2>&1 & + done + + openim::util::check_process_names ${SERVER_NAME} +} + +###################################### Linux Systemd ###################################### +SYSTEM_FILE_PATH="/etc/systemd/system/${SERVER_NAME}.service" + +# Print the necessary information after installation +function openim::push::info() { +cat << EOF +openim-push listen on: ${OPENIM_PUSH_HOST} +EOF +} + +# install openim-push +function openim::push::install() +{ + pushd ${OPENIM_ROOT} + + # 1. Build openim-push + make build BINS=${SERVER_NAME} + openim::common::sudo "cp ${OPENIM_OUTPUT_HOSTBIN}/${SERVER_NAME} ${OPENIM_INSTALL_DIR}/bin" + + openim::log::status "${SERVER_NAME} binary: ${OPENIM_INSTALL_DIR}/bin/${SERVER_NAME}" + + # 2. Generate and install the openim-push configuration file (openim-push.yaml) + echo ${LINUX_PASSWORD} | sudo -S bash -c \ + "./scripts/genconfig.sh ${ENV_FILE} deployments/templates/${SERVER_NAME}.yaml > ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml" + openim::log::status "${SERVER_NAME} config file: ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml" + + # 3. Create and install the ${SERVER_NAME} systemd unit file + echo ${LINUX_PASSWORD} | sudo -S bash -c \ + "./scripts/genconfig.sh ${ENV_FILE} deployments/templates/init/${SERVER_NAME}.service > ${SYSTEM_FILE_PATH}" + openim::log::status "${SERVER_NAME} systemd file: ${SYSTEM_FILE_PATH}" + + # 4. Start the openim-push service + openim::common::sudo "systemctl daemon-reload" + openim::common::sudo "systemctl restart ${SERVER_NAME}" + openim::common::sudo "systemctl enable ${SERVER_NAME}" + openim::push::status || return 1 + openim::push::info + + openim::log::info "install ${SERVER_NAME} successfully" + popd +} + +# Unload +function openim::push::uninstall() +{ + set +o errexit + openim::common::sudo "systemctl stop ${SERVER_NAME}" + openim::common::sudo "systemctl disable ${SERVER_NAME}" + openim::common::sudo "rm -f ${OPENIM_INSTALL_DIR}/bin/${SERVER_NAME}" + openim::common::sudo "rm -f ${OPENIM_CONFIG_DIR}/${SERVER_NAME}.yaml" + openim::common::sudo "rm -f /etc/systemd/system/${SERVER_NAME}.service" + set -o errexit + openim::log::info "uninstall ${SERVER_NAME} successfully" +} + +# Status Check +function openim::push::status() +{ + # Check the running status of the ${SERVER_NAME}. If active (running) is displayed, the ${SERVER_NAME} is started successfully. + systemctl status ${SERVER_NAME}|grep -q 'active' || { + openim::log::error "${SERVER_NAME} failed to start, maybe not installed properly" + return 1 + } + + # The listening port is hardcode in the configuration file + if echo | telnet 127.0.0.1 7071 2>&1|grep refused &>/dev/null;then # Assuming a different port for push + openim::log::error "cannot access health check port, ${SERVER_NAME} maybe not startup" + return 1 + fi +} + +if [[ "$*" =~ openim::push:: ]];then + eval $* +fi \ No newline at end of file diff --git a/scripts/install/openim-rpc.sh b/scripts/install/openim-rpc.sh new file mode 100755 index 000000000..7f6dfbfba --- /dev/null +++ b/scripts/install/openim-rpc.sh @@ -0,0 +1,181 @@ +#!/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 RPC Service Control Script +# +# Description: +# This script provides a control interface for the OpenIM RPC service within a Linux environment. It offers functionalities to start multiple RPC services, each denoted by their respective names under openim::rpc::service_name. +# +# Features: +# 1. Robust error handling using Bash built-ins like 'errexit', 'nounset', and 'pipefail'. +# 2. The capability to source common utility functions and configurations to ensure uniform environmental settings. +# 3. Comprehensive logging functionalities, providing a detailed understanding of operational processes. +# 4. Provision for declaring and managing a set of RPC services, each associated with its unique name and corresponding ports. +# 5. The ability to define and associate Prometheus ports for service monitoring purposes. +# 6. Functionalities to start each RPC service, along with its designated ports, in a sequence. +# +# Usage: +# 1. Direct Script Execution: +# This initiates all the RPC services declared under the function openim::rpc::service_name. +# Example: ./openim-rpc-{rpc-name}.sh openim::rpc::start +# 2. Controlling through Functions for systemctl operations: +# Specific operations like installation, uninstallation, and status check can be executed by passing the respective function name as an argument to the script. +# Example: ./openim-rpc-{rpc-name}.sh openim::rpc::install +# +# Note: Before executing this script, ensure that the necessary permissions are granted and relevant environmental variables are set. +# + + +set -o errexit +set +o nounset +set -o pipefail + +OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P) +[[ -z ${COMMON_SOURCED} ]] && source ${OPENIM_ROOT}/scripts/install/common.sh + +SERVER_NAME="openim-rpc" +readonly OPENIM_RPC_CONFIG=${OPENIM_ROOT}/config + +openim::rpc::service_name() { + local targets=( + openim-rpc-user + openim-rpc-friend + openim-rpc-msg + openim-rpc-group + openim-rpc-auth + openim-rpc-conversation + openim-rpc-third + ) + echo "${targets[@]}" +} +IFS=" " read -ra OPENIM_RPC_SERVICE_TARGETS <<< "$(openim::rpc::service_name)" +readonly OPENIM_RPC_SERVICE_TARGETS +readonly OPENIM_RPC_SERVICE_LISTARIES=("${OPENIM_RPC_SERVICE_TARGETS[@]##*/}") + +# Make sure the environment is only called via common to avoid too much nesting +openim::rpc::service_port() { + local targets=( + ${OPENIM_USER_PORT} # User service 10110 + ${OPENIM_FRIEND_PORT} # Friend service 10120 + ${OPENIM_MESSAGE_PORT} # Message service 10130 + # ${OPENIM_MESSAGE_GATEWAY_PORT} # Message gateway 10140 + ${OPENIM_GROUP_PORT} # Group service 10150 + ${OPENIM_AUTH_PORT} # Authorization service 10160 + # ${OPENIM_PUSH_PORT} # Push service 10170 + ${OPENIM_CONVERSATION_PORT} # Conversation service 10180 + ${OPENIM_THIRD_PORT} # Third-party service 10190 + ) + echo "${targets[@]}" +} +IFS=" " read -ra OPENIM_RPC_PORT_TARGETS <<< "$(openim::rpc::service_port)" +readonly OPENIM_RPC_PORT_TARGETS +readonly OPENIM_RPC_PORT_LISTARIES=("${OPENIM_RPC_PORT_TARGETS[@]##*/}") + +openim::rpc::prometheus_port() { + # Declare an array to hold all the Prometheus ports for different services + local targets=( + ${USER_PROM_PORT} # Prometheus port for user service + ${FRIEND_PROM_PORT} # Prometheus port for friend service + ${MESSAGE_PROM_PORT} # Prometheus port for message service + ${GROUP_PROM_PORT} # Prometheus port for group service + ${AUTH_PROM_PORT} # Prometheus port for authentication service + ${CONVERSATION_PROM_PORT} # Prometheus port for conversation service + ${THIRD_PROM_PORT} # Prometheus port for third-party integrations service + ) + # Print the list of ports + echo "${targets[@]}" +} +IFS=" " read -ra OPENIM_RPC_PROM_PORT_TARGETS <<< "$(openim::rpc::prometheus_port)" +readonly OPENIM_RPC_PROM_PORT_TARGETS +readonly OPENIM_RPC_PROM_PORT_LISTARIES=("${OPENIM_RPC_PROM_PORT_TARGETS[@]##*/}") + +function openim::rpc::start() { + echo "OPENIM_RPC_SERVICE_LISTARIES: ${OPENIM_RPC_SERVICE_LISTARIES[@]}" + echo "OPENIM_RPC_PROM_PORT_LISTARIES: ${OPENIM_RPC_PROM_PORT_LISTARIES[@]}" + echo "OPENIM_RPC_PORT_LISTARIES: ${OPENIM_RPC_PORT_LISTARIES[@]}" + + openim::log::info "Starting ${SERVER_NAME} ..." + + printf "+------------------------+-------+-----------------+\n" + printf "| Service Name | Port | Prometheus Port |\n" + printf "+------------------------+-------+-----------------+\n" + + length=${#OPENIM_RPC_SERVICE_LISTARIES[@]} + + for ((i=0; i<$length; i++)); do + printf "| %-22s | %-5s | %-15s |\n" "${OPENIM_RPC_SERVICE_LISTARIES[$i]}" "${OPENIM_RPC_PORT_LISTARIES[$i]}" "${OPENIM_RPC_PROM_PORT_LISTARIES[$i]}" + printf "+------------------------+-------+-----------------+\n" + done + + # start all rpc services + for ((i = 0; i < ${#OPENIM_RPC_SERVICE_LISTARIES[*]}; i++)); do + openim::util::stop_services_with_name ${OPENIM_RPC_SERVICE_LISTARIES[$i]} + openim::log::info "OpenIM ${OPENIM_RPC_SERVICE_LISTARIES[$i]} config path: ${OPENIM_RPC_CONFIG}" + + # Get the service and Prometheus ports. + OPENIM_RPC_SERVICE_PORTS=( $(openim::util::list-to-string ${OPENIM_RPC_PORT_LISTARIES[$i]}) ) + OPENIM_RPC_PROM_PORTS=( $(openim::util::list-to-string ${OPENIM_RPC_PROM_PORT_LISTARIES[$i]}) ) + + for ((j = 0; j < ${#OPENIM_RPC_SERVICE_PORTS[@]}; j++)); do + openim::log::info "Starting ${OPENIM_RPC_SERVICE_LISTARIES[$i]} service, port: ${OPENIM_RPC_SERVICE_PORTS[j]}, prometheus port: ${OPENIM_RPC_PROM_PORTS[j]}, binary root: ${OPENIM_OUTPUT_HOSTBIN}/${OPENIM_RPC_SERVICE_LISTARIES[$i]}" + openim::rpc::start_service "${OPENIM_RPC_SERVICE_LISTARIES[$i]}" "${OPENIM_RPC_SERVICE_PORTS[j]}" "${OPENIM_RPC_PROM_PORTS[j]}" + sleep 0.5 + done + done + + openim::util::check_ports ${OPENIM_RPC_PORT_TARGETS[@]} + # openim::util::check_ports ${OPENIM_RPC_PROM_PORT_TARGETS[@]} + +} + +function openim::rpc::start_service() { + local binary_name="$1" + local service_port="$2" + local prometheus_port="$3" + + local cmd="${OPENIM_OUTPUT_HOSTBIN}/${binary_name} --port ${service_port} -c ${OPENIM_RPC_CONFIG}" + + if [ -n "${prometheus_port}" ]; then + printf "Specifying prometheus port: %s\n" "${prometheus_port}" + cmd="${cmd} --prometheus_port ${prometheus_port}" + fi + nohup ${cmd} >> "${LOG_FILE}" 2>&1 & +} + +###################################### Linux Systemd ###################################### +SYSTEM_FILE_PATH="/etc/systemd/system/${SERVER_NAME}.service" + +function openim::rpc::install() { + openim::log::info "Installing ${SERVER_NAME} ..." +} + +function openim::rpc::uninstall() { + openim::log::info "Uninstalling ${SERVER_NAME} ..." + +} + +function openim::rpc::status() { + openim::log::info "Checking ${SERVER_NAME} status ..." + + openim::util::check_ports ${OPENIM_RPC_PORT_TARGETS[@]} + # openim::util::check_ports ${OPENIM_RPC_PROM_PORT_TARGETS[@]} + + openim::util::check_process_names ${SERVER_NAME} +} + +if [[ "$*" =~ openim::rpc:: ]];then + eval $* +fi \ No newline at end of file diff --git a/scripts/install/openim-tools.sh b/scripts/install/openim-tools.sh new file mode 100755 index 000000000..e913885a9 --- /dev/null +++ b/scripts/install/openim-tools.sh @@ -0,0 +1,166 @@ +#!/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 Tools Control Script +# +# Description: +# This script is responsible for managing the lifecycle of OpenIM tools, which include starting, stopping, +# and handling pre and post operations. It's designed to be modular and extensible, ensuring that the +# individual operations can be managed separately, and integrated seamlessly with Linux systemd. +# +# Features: +# 1. Robust error handling using Bash built-ins like 'errexit', 'nounset', and 'pipefail'. +# 2. The capability to source common utility functions and configurations to ensure uniform environmental settings. +# 3. Comprehensive logging functionalities, providing a detailed understanding of operational processes. +# 4. Provision for declaring and managing a set of OpenIM tools, each associated with its unique name and corresponding ports. +# 5. The ability to define and associate Prometheus ports for service monitoring purposes. +# 6. Functionalities to start each OpenIM tool, along with its designated ports, in a sequence. +# +# Usage: +# 1. Direct Script Execution: +# This initiates all the OpenIM tools declared under the function openim::tools::service_name. +# Example: ./openim-tools.sh openim::tools::start +# 2. Controlling through Functions for systemctl operations: +# Specific operations like installation, uninstallation, and status check can be executed by passing the respective function name as an argument to the script. +# Example: ./openim-tools.sh openim::tools::install +# + +set -o errexit +set +o nounset +set -o pipefail + +OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P) +[[ -z ${COMMON_SOURCED} ]] && source ${OPENIM_ROOT}/scripts/install/common.sh + +SERVER_NAME="openim-tools" + +openim::tools::start_name() { + local targets=( + imctl + ) + echo "${targets[@]}" +} +IFS=" " read -ra OPENIM_TOOLS_NAME_TARGETS <<< "$(openim::tools::start_name)" +readonly OPENIM_TOOLS_NAME_TARGETS +readonly OPENIM_TOOLS_NAME_LISTARIES=("${OPENIM_TOOLS_NAME_TARGETS[@]##*/}") + +openim::tools::pre_start_name() { + local targets=( + ncpu + component + ) + echo "${targets[@]}" +} +IFS=" " read -ra OPENIM_TOOLS_PRE_START_NAME_TARGETS <<< "$(openim::tools::pre_start_name)" +readonly OPENIM_TOOLS_PRE_START_NAME_TARGETS +readonly OPENIM_TOOLS_PRE_START_NAME_LISTARIES=("${OPENIM_TOOLS_PRE_START_NAME_TARGETS[@]##*/}") + +openim::tools::post_start_name() { + local targets=( + infra + ) + echo "${targets[@]}" +} +IFS=" " read -ra OPENIM_TOOLS_POST_START_NAME_TARGETS <<< "$(openim::tools::post_start_name)" +readonly OPENIM_TOOLS_POST_START_NAME_TARGETS +readonly OPENIM_TOOLS_POST_START_NAME_LISTARIES=("${OPENIM_TOOLS_POST_START_NAME_TARGETS[@]##*/}") + +function openim::tools::start_service() { + local binary_name="$1" + local config="$2" + local service_port="$3" + local prometheus_port="$4" + + local cmd="${OPENIM_OUTPUT_HOSTBIN_TOOLS}/${binary_name}" + openim::log::info "Starting PATH: ${OPENIM_OUTPUT_HOSTBIN_TOOLS}/${binary_name}..." + + if [ -n "${config}" ]; then + printf "Specifying config: %s\n" "${config}" + cmd="${cmd} -c ${config}/config.yaml" + fi + + if [ -n "${service_port}" ]; then + printf "Specifying service port: %s\n" "${service_port}" + cmd="${cmd} --port ${service_port}" + fi + + if [ -n "${prometheus_port}" ]; then + printf "Specifying prometheus port: %s\n" "${prometheus_port}" + cmd="${cmd} --prometheus_port ${prometheus_port}" + fi + openim::log::info "Starting ${binary_name}..." + ${cmd} +} + +function openim::tools::start() { + openim::log::info "Starting OpenIM Tools..." + for tool in "${OPENIM_TOOLS_NAME_LISTARIES[@]}"; do + openim::log::info "Starting ${tool}..." + # openim::tools::start_service ${tool} + sleep 0.2 + done +} + + +function openim::tools::pre-start() { + openim::log::info "Preparing to start OpenIM Tools..." + for tool in "${OPENIM_TOOLS_PRE_START_NAME_LISTARIES[@]}"; do + openim::log::info "Starting ${tool}..." + openim::tools::start_service ${tool} ${OPNEIM_CONFIG} + sleep 0.2 + done +} + +function openim::tools::post-start() { + openim::log::info "Post-start actions for OpenIM Tools..." + for tool in "${OPENIM_TOOLS_POST_START_NAME_LISTARIES[@]}"; do + openim::log::info "Starting ${tool}..." + # openim::tools::start_service ${tool} + sleep 0.2 + done +} + +function openim::tools::stop() { + openim::log::info "Stopping OpenIM Tools..." + for tool in "${OPENIM_TOOLS_NAME_LISTARIES[@]}"; do + openim::log::info "Stopping ${tool}..." + # Similarly, place the actual command to stop the tool here. + echo "Stopping service for ${tool}" + sleep 0.2 + done +} + +function openim::tools::pre-stop() { + openim::log::info "Preparing to stop OpenIM Tools..." + for tool in "${OPENIM_TOOLS_PRE_START_NAME_LISTARIES[@]}"; do + openim::log::info "Setting up pre-stop for ${tool}..." + echo "Pre-stop actions for ${tool}" + sleep 0.2 + done +} + +function openim::tools::post-stop() { + openim::log::info "Post-stop actions for OpenIM Tools..." + for tool in "${OPENIM_TOOLS_POST_START_NAME_LISTARIES[@]}"; do + openim::log::info "Executing post-stop for ${tool}..." + echo "Post-stop cleanup for ${tool}" + sleep 0.2 + done +} + +if [[ "$*" =~ openim::tools:: ]];then + eval $* +fi diff --git a/scripts/install/test.sh b/scripts/install/test.sh new file mode 100755 index 000000000..63a4957c6 --- /dev/null +++ b/scripts/install/test.sh @@ -0,0 +1,561 @@ +#!/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. + +# A set of helpers for tests + +openim::test::clear_all() { + if openim::test::if_supports_resource "rc" ; then + # shellcheck disable=SC2154 + # Disabling because "kube_flags" is set in a parent script + kubectl delete "${kube_flags[@]}" rc --all --grace-period=0 --force + fi + if openim::test::if_supports_resource "pods" ; then + kubectl delete "${kube_flags[@]}" pods --all --grace-period=0 --force + fi +} + +# Prints the calling file and line number $1 levels deep +# Defaults to 2 levels so you can call this to find your own caller +openim::test::get_caller() { + local levels=${1:-2} + local caller_file="${BASH_SOURCE[${levels}]}" + local caller_line="${BASH_LINENO[${levels}-1]}" + echo "$(basename "${caller_file}"):${caller_line}" +} + +# Force exact match of a returned result for a object query. Wrap this with || to support multiple +# valid return types. +# This runs `kubectl get` once and asserts that the result is as expected. +# $1: Object on which get should be run +# $2: The go-template to run on the result +# $3: The expected output +# $4: Additional args to be passed to kubectl +openim::test::get_object_assert() { + openim::test::object_assert 1 "$@" +} + +# Asserts that the output of a given get query is as expected. +# Runs the query multiple times before failing it. +# $1: Object on which get should be run +# $2: The go-template to run on the result +# $3: The expected output +# $4: Additional args to be passed to kubectl +openim::test::wait_object_assert() { + openim::test::object_assert 10 "$@" +} + +# Asserts that the output of a given get query is as expected. +# Can run the query multiple times before failing it. +# $1: Number of times the query should be run before failing it. +# $2: Object on which get should be run +# $3: The go-template to run on the result +# $4: The expected output +# $5: Additional args to be passed to kubectl +openim::test::object_assert() { + local tries=$1 + local object=$2 + local request=$3 + local expected=$4 + local args=${5:-} + + for j in $(seq 1 "${tries}"); do + # shellcheck disable=SC2086 + # Disabling because to allow for expansion here + res=$(kubectl get "${kube_flags[@]}" ${args} ${object} -o go-template="${request}") + if [[ "${res}" =~ ^$expected$ ]]; then + echo -n "${green}" + echo "$(openim::test::get_caller 3): Successful get ${object} ${request}: ${res}" + echo -n "${reset}" + return 0 + fi + echo "Waiting for Get ${object} ${request} ${args}: expected: ${expected}, got: ${res}" + sleep $((j-1)) + done + + echo "${bold}${red}" + echo "$(openim::test::get_caller 3): FAIL!" + echo "Get ${object} ${request}" + echo " Expected: ${expected}" + echo " Got: ${res}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 +} + +openim::test::get_object_jsonpath_assert() { + local object=$1 + local request=$2 + local expected=$3 + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + res=$(kubectl get "${kube_flags[@]}" ${object} -o jsonpath=${request}) + + if [[ "${res}" =~ ^$expected$ ]]; then + echo -n "${green}" + echo "$(openim::test::get_caller): Successful get ${object} ${request}: ${res}" + echo -n "${reset}" + return 0 + else + echo "${bold}${red}" + echo "$(openim::test::get_caller): FAIL!" + echo "Get ${object} ${request}" + echo " Expected: ${expected}" + echo " Got: ${res}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi +} + +openim::test::describe_object_assert() { + local resource=$1 + local object=$2 + local matches=( "${@:3}" ) + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + result=$(kubectl describe "${kube_flags[@]}" ${resource} ${object}) + + for match in "${matches[@]}"; do + if grep -q "${match}" <<< "${result}"; then + echo "matched ${match}" + else + echo "${bold}${red}" + echo "$(openim::test::get_caller): FAIL!" + echo "Describe ${resource} ${object}" + echo " Expected Match: ${match}" + echo " Not found in:" + echo "${result}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + done + + echo -n "${green}" + echo "$(openim::test::get_caller): Successful describe ${resource} ${object}:" + echo "${result}" + echo -n "${reset}" + return 0 +} + +openim::test::describe_object_events_assert() { + local resource=$1 + local object=$2 + local showevents=${3:-"true"} + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + if [[ -z "${3:-}" ]]; then + result=$(kubectl describe "${kube_flags[@]}" ${resource} ${object}) + else + result=$(kubectl describe "${kube_flags[@]}" "--show-events=${showevents}" ${resource} ${object}) + fi + + if grep -q "No events.\|Events:" <<< "${result}"; then + local has_events="true" + else + local has_events="false" + fi + if [[ "${showevents}" == "${has_events}" ]]; then + echo -n "${green}" + echo "$(openim::test::get_caller): Successful describe" + echo "${result}" + echo "${reset}" + return 0 + else + echo "${bold}${red}" + echo "$(openim::test::get_caller): FAIL" + if [[ "${showevents}" == "false" ]]; then + echo " Events information should not be described in:" + else + echo " Events information not found in:" + fi + echo "${result}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi +} + +openim::test::describe_resource_assert() { + local resource=$1 + local matches=( "${@:2}" ) + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + result=$(kubectl describe "${kube_flags[@]}" ${resource}) + + for match in "${matches[@]}"; do + if grep -q "${match}" <<< "${result}"; then + echo "matched ${match}" + else + echo "${bold}${red}" + echo "FAIL!" + echo "Describe ${resource}" + echo " Expected Match: ${match}" + echo " Not found in:" + echo "${result}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + done + + echo -n "${green}" + echo "Successful describe ${resource}:" + echo "${result}" + echo -n "${reset}" + return 0 +} + +openim::test::describe_resource_events_assert() { + local resource=$1 + local showevents=${2:-"true"} + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + result=$(kubectl describe "${kube_flags[@]}" "--show-events=${showevents}" ${resource}) + + if grep -q "No events.\|Events:" <<< "${result}"; then + local has_events="true" + else + local has_events="false" + fi + if [[ "${showevents}" == "${has_events}" ]]; then + echo -n "${green}" + echo "Successful describe" + echo "${result}" + echo -n "${reset}" + return 0 + else + echo "${bold}${red}" + echo "FAIL" + if [[ "${showevents}" == "false" ]]; then + echo " Events information should not be described in:" + else + echo " Events information not found in:" + fi + echo "${result}" + caller + echo "${reset}" + return 1 + fi +} + +openim::test::describe_resource_chunk_size_assert() { + # $1: the target resource + local resource=$1 + # $2: comma-separated list of additional resources that will be listed + local additionalResources=${2:-} + # Remaining args are flags to pass to kubectl + local args=${3:-} + + # Expect list requests for the target resource and the additional resources + local expectLists + IFS="," read -r -a expectLists <<< "${resource},${additionalResources}" + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + defaultResult=$(kubectl describe ${resource} --show-events=true -v=6 ${args} "${kube_flags[@]}" 2>&1 >/dev/null) + for r in "${expectLists[@]}"; do + if grep -q "${r}?.*limit=500" <<< "${defaultResult}"; then + echo "query for ${r} had limit param" + else + echo "${bold}${red}" + echo "FAIL!" + echo "Describe ${resource}" + echo " Expected limit param on request for: ${r}" + echo " Not found in:" + echo "${defaultResult}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + done + + # shellcheck disable=SC2086 + # Disabling to allow for expansion here + # Try a non-default chunk size + customResult=$(kubectl describe ${resource} --show-events=false --chunk-size=10 -v=6 ${args} "${kube_flags[@]}" 2>&1 >/dev/null) + if grep -q "${resource}?limit=10" <<< "${customResult}"; then + echo "query for ${resource} had user-specified limit param" + else + echo "${bold}${red}" + echo "FAIL!" + echo "Describe ${resource}" + echo " Expected limit param on request for: ${r}" + echo " Not found in:" + echo "${customResult}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + + echo -n "${green}" + echo "Successful describe ${resource} verbose logs:" + echo "${defaultResult}" + echo -n "${reset}" + + return 0 +} + +# Compare sort-by resource name output (first column, skipping first line) with expected order specify in the last parameter +openim::test::if_sort_by_has_correct_order() { + local var + var="$(echo "$1" | awk '{if(NR!=1) print $1}' | tr '\n' ':')" + openim::test::if_has_string "${var}" "${@:$#}" +} + +openim::test::if_has_string() { + local message=$1 + local match=$2 + + if grep -q "${match}" <<< "${message}"; then + echo -n "${green}" + echo "Successful" + echo -n "${reset}" + echo "message:${message}" + echo "has:${match}" + return 0 + else + echo -n "${bold}${red}" + echo "FAIL!" + echo -n "${reset}" + echo "message:${message}" + echo "has not:${match}" + caller + return 1 + fi +} + +openim::test::if_has_not_string() { + local message=$1 + local match=$2 + + if grep -q "${match}" <<< "${message}"; then + echo -n "${bold}${red}" + echo "FAIL!" + echo -n "${reset}" + echo "message:${message}" + echo "has:${match}" + caller + return 1 + else + echo -n "${green}" + echo "Successful" + echo -n "${reset}" + echo "message:${message}" + echo "has not:${match}" + return 0 + fi +} + +openim::test::if_empty_string() { + local match=$1 + if [ -n "${match}" ]; then + echo -n "${bold}${red}" + echo "FAIL!" + echo "${match} is not empty" + echo -n "${reset}" + caller + return 1 + else + echo -n "${green}" + echo "Successful" + echo -n "${reset}" + return 0 + fi +} + +# Returns true if the required resource is part of supported resources. +# Expects env vars: +# SUPPORTED_RESOURCES: Array of all resources supported by the apiserver. "*" +# means it supports all resources. For ex: ("*") or ("rc" "*") both mean that +# all resources are supported. +# $1: Name of the resource to be tested. +openim::test::if_supports_resource() { + SUPPORTED_RESOURCES=${SUPPORTED_RESOURCES:-""} + REQUIRED_RESOURCE=${1:-""} + + for r in "${SUPPORTED_RESOURCES[@]}"; do + if [[ "${r}" == "*" || "${r}" == "${REQUIRED_RESOURCE}" ]]; then + return 0 + fi + done + return 1 +} + +openim::test::version::object_to_file() { + name=$1 + flags=${2:-""} + file=$3 + # shellcheck disable=SC2086 + # Disabling because "flags" needs to allow for expansion here + kubectl version ${flags} | grep "${name} Version:" | sed -e s/"${name} Version: "/""/g > "${file}" +} + +openim::test::version::json_object_to_file() { + flags=$1 + file=$2 + # shellcheck disable=SC2086 + # Disabling because "flags" needs to allow for expansion here + kubectl version ${flags} --output json | sed -e s/' '/''/g -e s/'\"'/''/g -e s/'}'/''/g -e s/'{'/''/g -e s/'clientVersion:'/'clientVersion:,'/ -e s/'serverVersion:'/'serverVersion:,'/ | tr , '\n' > "${file}" +} + +openim::test::version::json_client_server_object_to_file() { + flags=$1 + name=$2 + file=$3 + # shellcheck disable=SC2086 + # Disabling because "flags" needs to allow for expansion here + kubectl version ${flags} --output json | jq -r ".${name}" | sed -e s/'\"'/''/g -e s/'}'/''/g -e s/'{'/''/g -e /^$/d -e s/','/''/g -e s/':'/'='/g > "${file}" +} + +openim::test::version::yaml_object_to_file() { + flags=$1 + file=$2 + # shellcheck disable=SC2086 + # Disabling because "flags" needs to allow for expansion here + kubectl version ${flags} --output yaml | sed -e s/' '/''/g -e s/'\"'/''/g -e /^$/d > "${file}" +} + +openim::test::version::diff_assert() { + local original=$1 + local comparator=${2:-"eq"} + local latest=$3 + local diff_msg=${4:-""} + local res="" + + if [ ! -f "${original}" ]; then + echo "${bold}${red}" + echo "FAIL! ${diff_msg}" + echo "the file '${original}' does not exit" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + + if [ ! -f "${latest}" ]; then + echo "${bold}${red}" + echo "FAIL! ${diff_msg}" + echo "the file '${latest}' does not exit" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + + if [ "${comparator}" == "exact" ]; then + # Skip sorting of file content for exact comparison. + cp "${original}" "${original}.sorted" + cp "${latest}" "${latest}.sorted" + else + sort "${original}" > "${original}.sorted" + sort "${latest}" > "${latest}.sorted" + fi + + if [ "${comparator}" == "eq" ] || [ "${comparator}" == "exact" ]; then + if [ "$(diff -iwB "${original}".sorted "${latest}".sorted)" == "" ] ; then + echo -n "${green}" + echo "Successful: ${diff_msg}" + echo -n "${reset}" + return 0 + else + echo "${bold}${red}" + echo "FAIL! ${diff_msg}" + echo " Expected: " + cat "${original}" + echo " Got: " + cat "${latest}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + else + if [ -n "$(diff -iwB "${original}".sorted "${latest}".sorted)" ] ; then + echo -n "${green}" + echo "Successful: ${diff_msg}" + echo -n "${reset}" + return 0 + else + echo "${bold}${red}" + echo "FAIL! ${diff_msg}" + echo " Expected: " + cat "${original}" + echo " Got: " + cat "${latest}" + echo "${reset}${red}" + caller + echo "${reset}" + return 1 + fi + fi +} + +# Force exact match of kubectl stdout, stderr, and return code. +# $1: file with actual stdout +# $2: file with actual stderr +# $3: the actual return code +# $4: file with expected stdout +# $5: file with expected stderr +# $6: expected return code +# $7: additional message describing the invocation +openim::test::results::diff() { + local actualstdout=$1 + local actualstderr=$2 + local actualcode=$3 + local expectedstdout=$4 + local expectedstderr=$5 + local expectedcode=$6 + local message=$7 + local result=0 + + if ! openim::test::version::diff_assert "${expectedstdout}" "exact" "${actualstdout}" "stdout for ${message}"; then + result=1 + fi + if ! openim::test::version::diff_assert "${expectedstderr}" "exact" "${actualstderr}" "stderr for ${message}"; then + result=1 + fi + if [ "${actualcode}" -ne "${expectedcode}" ]; then + echo "${bold}${red}" + echo "$(openim::test::get_caller): FAIL!" + echo "Return code for ${message}" + echo " Expected: ${expectedcode}" + echo " Got: ${actualcode}" + echo "${reset}${red}" + caller + echo "${reset}" + result=1 + fi + + if [ "${result}" -eq 0 ]; then + echo -n "${green}" + echo "$(openim::test::get_caller): Successful: ${message}" + echo -n "${reset}" + fi + + return "$result" +} \ No newline at end of file diff --git a/scripts/install/vimrc b/scripts/install/vimrc new file mode 100644 index 000000000..b128951c6 --- /dev/null +++ b/scripts/install/vimrc @@ -0,0 +1,300 @@ +" learn: https://github.com/cubxxw/awesome-cs-course/tree/master/linux +" Read: https://github.com/cubxxw/awesome-cs-course/blob/master/linux/markdown/my_vim.md + +"vim的配置关于鼠标滚动滑动""" +if has("autocmd") + au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif + set mouse=a +endif +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +"C,C++ 按F5编译运行 +map :call CompileRunGcc() +func! CompileRunGcc() + exec "w" + if &filetype == 'c' + exec "!g++ % -o %<" + exec "! ./%<" + elseif &filetype == 'cpp' + exec "!g++ % -o %<" + exec "! ./%<" + elseif &filetype == 'java' + exec "!javac %" + exec "!java %<" + elseif &filetype == 'sh' + :!./% + endif +endfunc +"配置命令" +"C,C++的调试 +"''''''''''''''''""""""""""""""""""""""""""""""""""''''''''''''''''''''' +map :call Rungdb() +func! Rungdb() + exec "w" + exec "!g++ % -g -o %<" + exec "!gdb ./%<" +endfunc + +""实用设置 +" 设置当文件被改动时自动载入 +set autoread +" quickfix模式 +autocmd FileType c,cpp map :w:make +"代码补全 +set completeopt=preview,menu + +" common configure +"set noswapfile +set mouse=a " 激活鼠标使用 +set wrap " 自动换行 +set sw=4 " 设置软宽度 +set gdefault " 行内替换 +set nu +set showmatch " 高亮显示括号匹配 +set expandtab " 使用空格来替换 Tab +set tabstop=4 " 设置 Tab 长度为 4 空格 +set shiftwidth=4 " 设置自动缩进长度为 4 空格 +set autoindent " 继承前一行的缩进方式,适用于多行注释" +set autowrite " 自动保存 +set nocompatible " 关闭 vi 兼容模式 +set history=1000 " 设置历史记录步数 +set confirm " 在处理未保存或只读文件时,弹出确认 + +" 搜索逐字符高亮 +set hlsearch +set incsearch + +" 从不备份 +set nobackup +set noswapfile + +let g:indentLine_enabled=0 + +" golang configure ====> start +let g:go_highlight_methods = 1 +let g:go_highlight_operators = 1 +let g:go_highlight_build_constraints = 1 +let g:go_fmt_autosave = 1 +let g:go_version_warning = 1 +let g:go_autodetect_gopath = 1 +let g:go_highlight_types = 1 +let g:go_highlight_fields = 1 +let g:go_highlight_functions = 1 +let g:go_highlight_function_calls = 1 +let g:go_highlight_extra_types = 1 +let g:go_highlight_generate_tags = 1 +let g:go_def_mode = 'gopls' +let g:go_gopls_enabled = 1 +let g:go_guru_enabled = 1 +let g:go_fmt_experimental = 1 +let g:go_def_mapping_enabled = 1 +let g:go_build_tags = '-v' +let g:go_fmt_command = "goimports" +let g:go_list_type = "quickfix" +let g:go_def_mapping_enable = 1 + +map <2-LeftMouse> :GoDef +map :GoDefPop +map :GoCallers +map :GoCallees +map +map +unmap +map :GoDef +map :GoDefPop +map :GoDoc +map :GoInfo +map :GoDefType +map :GoAddTag +map :GoImplements +map :GoRename +map :GoFillStruct +map :GoCallers +map :GoSameIdsToggle + +augroup go + autocmd! + + " Show by default 4 spaces for a tab + autocmd BufNewFile,BufRead *.go setlocal noexpandtab tabstop=4 shiftwidth=4 + + " :GoDef but opens in a vertical split + autocmd FileType go nmap v (go-def-vertical) + " :GoDef but opens in a horizontal split + autocmd FileType go nmap s (go-def-split) + + " :GoAlternate commands :A, :AV, :AS and :AT + autocmd Filetype go command! -bang A call go#alternate#Switch(0, 'edit') + autocmd Filetype go command! -bang AV call go#alternate#Switch(0, 'vsplit') + autocmd Filetype go command! -bang AS call go#alternate#Switch(0, 'split') + autocmd Filetype go command! -bang AT call go#alternate#Switch(0, 'tabe') +augroup END + +" build_go_files is a custom function that builds or compiles the test file. +" It calls :GoBuild if its a Go file, or :GoTestCompile if it's a test file +function! s:build_go_files() + let l:file = expand('%') + if l:file =~# '^\f\+_test\.go$' + call go#test#Test(0, 1) + elseif l:file =~# '^\f\+\.go$' + call go#cmd#Build(0) + endif +endfunction +" golang configure ====> end + +:inoremap ( ()i +:inoremap ) =ClosePair(')') +:inoremap { {}O +:inoremap } =ClosePair('}') +:inoremap [ []i +:inoremap ] =ClosePair(']') +:inoremap " ""i +:inoremap ' ''i +function! ClosePair(char) + if getline('.')[col('.') - 1] == a:char + return "\" + else + return a:char + endif +endfunction +filetype plugin indent on +"打开文件类型检测, 加了这句才可以用智能补全 + +set completeopt=longest,menu + +""""""""""""""""""""""""""""""""""""""""""""""" + noremap :set nu + noremap :!python3 a + noremap :set ai + noremap :syntax on + set cursorline " 突出显示当前行 + set magic " 设置魔术 + "" noremap :! g++ -o a +nnoremap +nnoremap +nnoremap +nnoremap +nmap wj :resize -3 +nmap wk :resize +3 +nmap wh :vertical resize -3 +nmap wl :vertical resize +3 +set guifont=Droid\ Sans\ Mono\ Nerd\ Font\ Complete:h18 " 设置字体 +set guicursor=n-v-c:ver5 " 设置光标为竖线 +set number ""# 显示行号 +set autowrite "" # 自动保存 +set ruler ""# 显示打开状态栏标尺 +set cursorline "" # 突出显示当前行 + +set showmatch "" # 匹配光标所经过的括号等. +set showcmd ""# 命令行显示输入的命令 +set showmode ""命令行显示vim当前模式 +set showtabline=0 " 隐藏Tab栏 +set laststatus=2 """"'vim 窗口底部显示永久状态栏,显示文件名,行号,列号等. +let mapleader = "," " 定义键 +set nocompatible " 设置不兼容原始vi模式 +filetype on " 设置开启文件类型侦测 +filetype plugin on " 设置加载对应文件类型的插件 +set noeb " 关闭错误的提示 +syntax enable " 开启语法高亮功能 +syntax on " 自动语法高亮 +set cmdheight=2 " 设置命令行的高度 +set showcmd " select模式下显示选中的行数 +set ruler " 总是显示光标位置 +set laststatus=2 " 总是显示状态栏 +set number " 开启行号显示 +set cursorline " 高亮显示当前行 +set whichwrap+=<,>,h,l " 设置光标键跨行 +set ttimeoutlen=0 " 设置键响应时间 +set virtualedit=block,onemore " 允许光标出现在最后一个字符的后面 + +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" 代码缩进和排版 +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +set autoindent " 设置自动缩进 +set cindent " 设置使用C/C++语言的自动缩进方式 +set cinoptions=g0,:0,N-s,(0 " 设置C/C++语言的具体缩进方式 +set smartindent " 智能的选择对其方式 +filetype indent on " 自适应不同语言的智能缩进 +set expandtab " 将制表符扩展为空格 +set tabstop=4 " 设置编辑时制表符占用空格数 +set shiftwidth=4 " 设置格式化时制表符占用空格数 +set softtabstop=4 " 设置4个空格为制表符 +set smarttab " 在行和段开始处使用制表符 +set nowrap " 禁止折行 +set backspace=2 " 使用回车键正常处理indent,eol,start等 +set sidescroll=10 " 设置向右滚动字符数 +set nofoldenable " 禁用折叠代码 + +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" 代码补全 +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +set wildmenu " vim自身命名行模式智能补全 +set completeopt-=preview " 补全时不显示窗口,只显示补全列表 + +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" 搜索设置 +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +set hlsearch " 高亮显示搜索结果 +set incsearch " 开启实时搜索功能 +set ignorecase " 搜索时大小写不敏感 + +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" 缓存设置 +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +set nobackup " 设置不备份 +set noswapfile " 禁止生成临时文件 +set autoread " 文件在vim之外修改过,自动重新读入 +set autowrite " 设置自动保存 +set confirm " 在处理未保存或只读文件的时候,弹出确认 + +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +"调整窗 +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +nmap wj :resize -3 +nmap wk :resize +3 +nmap wh :vertical resize -3 +nmap wl :vertical resize +3 + +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +"编码" +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +set langmenu=zh_CN.UTF-8 +set helplang=cn +set termencoding=utf-8 +set encoding=utf8 +set fileencodings=utf8,ucs-bom,gbk,cp936,gb2312,gb18030 + +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +"代码补全“ +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +inoremap ' ''i +inoremap " ""i +inoremap ( ()i +inoremap [ []i +inoremap { {}O + : set nu + : set ai + : syntax on + : filetype on + set tabstop=4 + set ignorecase +noremap h +noremap j +noremap r +noremap l +" Specify a directory for plugins +" - For Neovim: stdpath('data') . '/plugged' +" - Avoid using standard Vim directory names like 'plugin' +let g:coc_disable_startup_warning = 1 + +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +"tmux" +"复用终端、分屏" +"let g:EasyMotion_startofline = 0 " keep cursor colum when JK motion +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +map h (easymotion-linebackward) +map j (easymotion-j) +map k (easymotion-k) +map l (easymotion-lineforward) +" 重复上一次操作, 类似repeat插件, 很强大 +map . (easymotion-repeat) +nmap s (easymotion-s) diff --git a/scripts/install_im_compose.sh b/scripts/install_im_compose.sh index 00191334a..04504089a 100755 --- a/scripts/install_im_compose.sh +++ b/scripts/install_im_compose.sh @@ -1,3 +1,5 @@ +#!/usr/bin/env bash + # Copyright © 2023 OpenIM. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,110 +15,62 @@ # limitations under the License. -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/scripts/lib/init.sh" +source "${OPENIM_ROOT}/scripts/install/environment.sh" + +openim::util::onCtrlC -# docker-compose.yaml file name docker_compose_file_name="docker-compose.yaml" -trap 'onCtrlC' INT -function onCtrlC () { - #Capture CTRL+C, terminate the background process of the program when the script is terminated in the form of ctrl+c - kill -9 ${do_sth_pid} ${progress_pid} - echo - echo 'Ctrl+C is captured' - exit 1 +# Load environment variables from .env file +load_env() { + source ${OPENIM_ROOT}/.env } -do_sth() { - #Main program to run - echo "++++++++++++++++++++++++" - sleep 5 - echo "++++++++++++++++++++++++" - - sleep 10 -} - -#Import environment variables -source .env - -#Get the public IP address of the local machine -internet_ip=$(curl ifconfig.me -s) -echo -e "\033[1;34mCurrent public IP address: ${internet_ip}\033[0m\n" - -#If MINIO_ENDPOINT is "http://127.0.0.1:10005", replace it with the current public IP address -if [[ $MINIO_ENDPOINT == "http://127.0.0.1:10005" ]]; then - sed -i "s/127.0.0.1/${internet_ip}/" .env -fi - -do_progress_bar() { - local duration=${1} - local max_progress=20 - local current_progress=0 - - while true; do - ((current_progress++)) - if [[ $current_progress -gt $max_progress ]]; then - break - fi - sleep "$duration" - echo "=====> Progress: [${current_progress}/${max_progress}]" - done -} - -#Start Docker containers -start_docker_containers() { - if command -v docker-compose >/dev/null 2>&1; then - echo -e "\033[1;34mFound docker-compose command, starting docker containers...\033[0m\n" - docker-compose -f ${OPENIM_ROOT}/${docker_compose_file_name} up -d - else - if command -v docker >/dev/null 2>&1; then - echo -e "\033[1;34mFound docker command, starting docker containers...\033[0m\n" - docker compose -f ${OPENIM_ROOT}/${docker_compose_file_name} up -d - else - echo -e "\033[1;31mFailed to find docker-compose or docker command, please make sure they are installed and configured correctly.\033[0m" - return 1 - fi +# Replace local IP with public IP in .env +replace_ip() { + if [ "$API_URL" == "http://127.0.0.1:10002/object/" ]; then + sed -i "s/127.0.0.1/${internet_ip}/" ${OPENIM_ROOT}/.env fi + + if [ "$MINIO_ENDPOINT" == "http://127.0.0.1:10005" ]; then + sed -i "s/127.0.0.1/${internet_ip}/" ${OPENIM_ROOT}/.env + fi + + openim::log::info "Your minio endpoint is ${MINIO_ENDPOINT}" } -#Execute scripts -setup_script() { - chmod +x ${SCRIPTS_ROOT}/*.sh - echo -e "\033[1;34m============>Executing init_pwd.sh script...\033[0m\n" - ${SCRIPTS_ROOT}/init_pwd.sh - echo -e "\033[1;34m============>Executing env_check.sh script...\033[0m\n" - ${SCRIPTS_ROOT}/env_check.sh +# Execute necessary scripts +execute_scripts() { + chmod +x ${OPENIM_ROOT}/scripts/*.sh + openim::log::info "Executing init_pwd.sh" + ${OPENIM_ROOT}/scripts/init_pwd.sh + + openim::log::info "Executing env_check.sh" + ${OPENIM_ROOT}/scripts/env_check.sh } -setup_script & +# Start docker compose +start_docker_compose() { + openim::log::info "Checking if docker-compose command is available" + if command -v docker-compose &> /dev/null; then + docker-compose up -d + else + docker compose up -d + fi -#Start Docker containers (timeout 10 seconds) -start_docker_containers + ${OPENIM_ROOT}/scripts/docker-check-service.sh +} -docker_pid=$! -timeout 10s tail --pid=${docker_pid} -f /dev/null -docker_exit_code=$? +main() { + load_env + openim::util::get_server_ip + replace_ip + execute_scripts + start_docker_compose + openim::log::success "Script executed successfully" +} -if [ $docker_exit_code -eq 0 ]; then - echo -e "\033[1;32m============>Docker containers started successfully!\033[0m\n" -else - echo -e "\033[1;31m============>Failed to start Docker containers, please check the environment configuration and dependencies.\033[0m\n" - exit 1 -fi - -echo -e "\033[1;34m============>Executing docker_check_service.sh script...\033[0m\n" - -#View running Docker containers -echo -e "\033[1;34m============>Viewing running Docker containers...\033[0m\n" -echo "" -docker ps - -#Replace the progress bar section with the pv command -echo -e "\033[1;34m============>Starting progress bar...\033[0m\n" -do_progress_bar 0.5 | pv -l -s 20 > /dev/null -echo -e "\033[1;34m============>Progress bar completed.\033[0m\n" - -#Execute the main program -do_sth +# Run the main function +main \ No newline at end of file diff --git a/scripts/install_im_server.sh b/scripts/install_im_server.sh deleted file mode 100755 index 0961193f1..000000000 --- a/scripts/install_im_server.sh +++ /dev/null @@ -1,85 +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. - - -# Common utilities, variables and checks for all build scripts. -set -o errexit -set -o nounset -set -o pipefail - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -source $SCRIPTS_ROOT/style_info.sh - -# docker-compose.yaml file name -docker_compose_file_name="docker-compose.yaml" - -trap 'onCtrlC' INT -function onCtrlC () { - #Capture CTRL+C, terminate the background process of the program when the script is terminated in the form of ctrl+c - kill -9 ${do_sth_pid} ${progress_pid} - echo - echo 'Ctrl+C is captured' - exit 1 -} - -# Load environment variables from .env file -source ${OPENIM_ROOT}/.env - -# Get the public internet IP address -internet_ip=$(curl ifconfig.me -s) -echo -e "${PURPLE_PREFIX}=========> Your public internet IP address is ${internet_ip} ${COLOR_SUFFIX} \n" - -# Replace local IP address with the public IP address in .env file -if [ $API_URL == "http://127.0.0.1:10002/object/" ]; then - sed -i "s/127.0.0.1/${internet_ip}/" ${OPENIM_ROOT}/.env -fi - -if [ $MINIO_ENDPOINT == "http://127.0.0.1:10005" ]; then - sed -i "s/127.0.0.1/${internet_ip}/" ${OPENIM_ROOT}/.env -fi - - - - -echo -e "${PURPLE_PREFIX}=========> Your minio endpoint is ${MINIO_ENDPOINT} ${COLOR_SUFFIX} \n" - -# Change directory to scripts folder - -chmod +x ${SCRIPTS_ROOT}/*.sh - -# Execute necessary scripts -echo -e "${PURPLE_PREFIX}=========> init_pwd.sh ${COLOR_SUFFIX} \n" - -${SCRIPTS_ROOT}/init_pwd.sh - -echo -e "${PURPLE_PREFIX}=========> env_check.sh ${COLOR_SUFFIX} \n" - -${SCRIPTS_ROOT}/env_check.sh - -# Go back to the previous directory -cd ${OPENIM_ROOT} - -# Check if docker-compose command is available -if command -v docker-compose &> /dev/null -then - docker-compose up -d -else - docker compose up -d -fi - -${SCRIPTS_ROOT}/docker_check_service.sh diff --git a/scripts/lib/chat.sh b/scripts/lib/chat.sh new file mode 100755 index 000000000..a0eb49db0 --- /dev/null +++ b/scripts/lib/chat.sh @@ -0,0 +1,178 @@ +# 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. + +# A set of helpers for starting/running chat for tests + +CHAT_VERSION=${CHAT_VERSION:-1.1.0} +CHAT_HOST=${CHAT_HOST:-127.0.0.1} +CHAT_PORT=${CHAT_PORT:-2379} +# This is intentionally not called CHAT_LOG_LEVEL: +# chat checks that and compains when it is set in addition +# to the command line argument, even when both have the same value. +CHAT_LOGLEVEL=${CHAT_LOGLEVEL:-warn} +export OPENIM_INTEGRATION_CHAT_URL="http://${CHAT_HOST}:${CHAT_PORT}" + +openim::chat::validate() { + # validate if in path + command -v chat >/dev/null || { + openim::log::usage "chat must be in your PATH" + openim::log::info "You can use 'hack/install-chat.sh' to install a copy in third_party/." + exit 1 + } + + # validate chat port is free + local port_check_command + if command -v ss &> /dev/null && ss -Version | grep 'iproute2' &> /dev/null; then + port_check_command="ss" + elif command -v netstat &>/dev/null; then + port_check_command="netstat" + else + openim::log::usage "unable to identify if chat is bound to port ${CHAT_PORT}. unable to find ss or netstat utilities." + exit 1 + fi + if ${port_check_command} -nat | grep "LISTEN" | grep "[\.:]${CHAT_PORT:?}" >/dev/null 2>&1; then + openim::log::usage "unable to start chat as port ${CHAT_PORT} is in use. please stop the process listening on this port and retry." + openim::log::usage "$(${port_check_command} -nat | grep "LISTEN" | grep "[\.:]${CHAT_PORT:?}")" + exit 1 + fi + + # need set the env of "CHAT_UNSUPPORTED_ARCH" on unstable arch. + arch=$(uname -m) + if [[ $arch =~ arm* ]]; then + export CHAT_UNSUPPORTED_ARCH=arm + fi + # validate installed version is at least equal to minimum + version=$(chat --version | grep Version | head -n 1 | cut -d " " -f 3) + if [[ $(openim::chat::version "${CHAT_VERSION}") -gt $(openim::chat::version "${version}") ]]; then + export PATH=${OPENIM_ROOT}/third_party/chat:${PATH} + hash chat + echo "${PATH}" + version=$(chat --version | grep Version | head -n 1 | cut -d " " -f 3) + if [[ $(openim::chat::version "${CHAT_VERSION}") -gt $(openim::chat::version "${version}") ]]; then + openim::log::usage "chat version ${CHAT_VERSION} or greater required." + openim::log::info "You can use 'hack/install-chat.sh' to install a copy in third_party/." + exit 1 + fi + fi +} + +openim::chat::version() { + printf '%s\n' "${@}" | awk -F . '{ printf("%d%03d%03d\n", $1, $2, $3) }' +} + +openim::chat::start() { + # validate before running + openim::chat::validate + + # Start chat + CHAT_DIR=${CHAT_DIR:-$(mktemp -d 2>/dev/null || mktemp -d -t test-chat.XXXXXX)} + if [[ -d "${ARTIFACTS:-}" ]]; then + CHAT_LOGFILE="${ARTIFACTS}/chat.$(uname -n).$(id -un).log.DEBUG.$(date +%Y%m%d-%H%M%S).$$" + else + CHAT_LOGFILE=${CHAT_LOGFILE:-"/dev/null"} + fi + openim::log::info "chat --advertise-client-urls ${OPENIM_INTEGRATION_CHAT_URL} --data-dir ${CHAT_DIR} --listen-client-urls http://${CHAT_HOST}:${CHAT_PORT} --log-level=${CHAT_LOGLEVEL} 2> \"${CHAT_LOGFILE}\" >/dev/null" + chat --advertise-client-urls "${OPENIM_INTEGRATION_CHAT_URL}" --data-dir "${CHAT_DIR}" --listen-client-urls "${OPENIM_INTEGRATION_CHAT_URL}" --log-level="${CHAT_LOGLEVEL}" 2> "${CHAT_LOGFILE}" >/dev/null & + CHAT_PID=$! + + echo "Waiting for chat to come up." + openim::util::wait_for_url "${OPENIM_INTEGRATION_CHAT_URL}/health" "chat: " 0.25 80 + curl -fs -X POST "${OPENIM_INTEGRATION_CHAT_URL}/v3/kv/put" -d '{"key": "X3Rlc3Q=", "value": ""}' +} + +openim::chat::start_scraping() { + if [[ -d "${ARTIFACTS:-}" ]]; then + CHAT_SCRAPE_DIR="${ARTIFACTS}/chat-scrapes" + else + CHAT_SCRAPE_DIR=$(mktemp -d -t test.XXXXXX)/chat-scrapes + fi + openim::log::info "Periodically scraping chat to ${CHAT_SCRAPE_DIR} ." + mkdir -p "${CHAT_SCRAPE_DIR}" + ( + while sleep 30; do + openim::chat::scrape + done + ) & + CHAT_SCRAPE_PID=$! +} + +openim::chat::scrape() { + curl -s -S "${OPENIM_INTEGRATION_CHAT_URL}/metrics" > "${CHAT_SCRAPE_DIR}/next" && mv "${CHAT_SCRAPE_DIR}/next" "${CHAT_SCRAPE_DIR}/$(date +%s).scrape" +} + +openim::chat::stop() { + if [[ -n "${CHAT_SCRAPE_PID:-}" ]] && [[ -n "${CHAT_SCRAPE_DIR:-}" ]] ; then + kill "${CHAT_SCRAPE_PID}" &>/dev/null || : + wait "${CHAT_SCRAPE_PID}" &>/dev/null || : + openim::chat::scrape || : + ( + # shellcheck disable=SC2015 + cd "${CHAT_SCRAPE_DIR}"/.. && \ + tar czf chat-scrapes.tgz chat-scrapes && \ + rm -rf chat-scrapes || : + ) + fi + if [[ -n "${CHAT_PID-}" ]]; then + kill "${CHAT_PID}" &>/dev/null || : + wait "${CHAT_PID}" &>/dev/null || : + fi +} + +openim::chat::clean_chat_dir() { + if [[ -n "${CHAT_DIR-}" ]]; then + rm -rf "${CHAT_DIR}" + fi +} + +openim::chat::cleanup() { + openim::chat::stop + openim::chat::clean_chat_dir +} + +openim::chat::install() { + ( + local os + local arch + + os=$(openim::util::host_os) + arch=$(openim::util::host_arch) + + cd "${OPENIM_ROOT}/third_party" || return 1 + if [[ $(readlink chat) == chat-v${CHAT_VERSION}-${os}-* ]]; then + openim::log::info "chat v${CHAT_VERSION} already installed. To use:" + openim::log::info "export PATH=\"$(pwd)/chat:\${PATH}\"" + return #already installed + fi + + if [[ ${os} == "darwin" ]]; then + download_file="chat-v${CHAT_VERSION}-${os}-${arch}.zip" + url="https://github.com/chat-io/chat/releases/download/v${CHAT_VERSION}/${download_file}" + openim::util::download_file "${url}" "${download_file}" + unzip -o "${download_file}" + ln -fns "chat-v${CHAT_VERSION}-${os}-${arch}" chat + rm "${download_file}" + elif [[ ${os} == "linux" ]]; then + url="https://github.com/coreos/chat/releases/download/v${CHAT_VERSION}/chat-v${CHAT_VERSION}-${os}-${arch}.tar.gz" + download_file="chat-v${CHAT_VERSION}-${os}-${arch}.tar.gz" + openim::util::download_file "${url}" "${download_file}" + tar xzf "${download_file}" + ln -fns "chat-v${CHAT_VERSION}-${os}-${arch}" chat + rm "${download_file}" + else + openim::log::info "${os} is NOT supported." + fi + openim::log::info "chat v${CHAT_VERSION} installed. To use:" + openim::log::info "export PATH=\"$(pwd)/chat:\${PATH}\"" + ) +} \ No newline at end of file diff --git a/scripts/lib/color.sh b/scripts/lib/color.sh index e6b9c3924..207af1d41 100755 --- a/scripts/lib/color.sh +++ b/scripts/lib/color.sh @@ -14,24 +14,47 @@ # See the License for the specific language governing permissions and # limitations under the License. +# this script is used to install the dependencies of the project +# +# Usage: `scripts/color.sh`. +################################################################################ + +# shellcheck disable=SC2034 +if [[ ! -v COLOR_OPEN ]]; then + COLOR_OPEN=1 +fi + +# Function for colored echo +openim::color::echo() { + COLOR=$1 + [ $COLOR_OPEN -eq 1 ] && echo -e "${COLOR} $(date '+%Y-%m-%d %H:%M:%S') $@ ${COLOR_SUFFIX}" + shift +} # Define color variables -# Feature +# --- Feature --- COLOR_NORMAL='\033[0m';COLOR_BOLD='\033[1m';COLOR_DIM='\033[2m';COLOR_UNDER='\033[4m'; COLOR_ITALIC='\033[3m';COLOR_NOITALIC='\033[23m';COLOR_BLINK='\033[5m'; COLOR_REVERSE='\033[7m';COLOR_CONCEAL='\033[8m';COLOR_NOBOLD='\033[22m'; COLOR_NOUNDER='\033[24m';COLOR_NOBLINK='\033[25m'; -# Front color -COLOR_BLACK='\033[30m';COLOR_RED='\033[31m';COLOR_GREEN='\033[32m';COLOR_YELLOW='\033[33m'; -COLOR_BLUE='\033[34m';COLOR_MAGENTA='\033[35m';COLOR_CYAN='\033[36m';COLOR_WHITE='\033[37m'; +# --- Front color --- +COLOR_BLACK='\033[30m'; +COLOR_RED='\033[31m'; +COLOR_GREEN='\033[32m'; +COLOR_YELLOW='\033[33m'; +COLOR_BLUE='\033[34m'; +COLOR_MAGENTA='\033[35m'; +COLOR_CYAN='\033[36m'; +COLOR_WHITE='\033[37m'; -# background color +# --- background color --- COLOR_BBLACK='\033[40m';COLOR_BRED='\033[41m'; COLOR_BGREEN='\033[42m';COLOR_BYELLOW='\033[43m'; COLOR_BBLUE='\033[44m';COLOR_BMAGENTA='\033[45m'; COLOR_BCYAN='\033[46m';COLOR_BWHITE='\033[47m'; +# --- Color definitions --- # Color definitions COLOR_SUFFIX="\033[0m" # End all colors and special effects BLACK_PREFIX="\033[30m" # Black prefix @@ -44,31 +67,18 @@ WHITE_PREFIX="\033[37m" # White prefix BOLD_PREFIX="\033[1m" # Bold prefix UNDERLINE_PREFIX="\033[4m" # Underline prefix ITALIC_PREFIX="\033[3m" # Italic prefix -BRIGHT_GREEN_PREFIX='\033[1;32m' # Bright green prefix CYAN_PREFIX="\033[0;36m" # Cyan prefix -# --- helper functions for logs --- -info() -{ - echo -e "[${GREEN_PREFIX}INFO${COLOR_SUFFIX}] " "$@" -} -warn() -{ - echo -e "[${YELLOW_PREFIX}WARN${COLOR_SUFFIX}] " "$@" >&2 -} -fatal() -{ - echo -e "[${RED_PREFIX}ERROR${COLOR_SUFFIX}] " "$@" >&2 - exit 1 -} -debug() -{ - echo -e "[${BLUE_PREFIX}DEBUG${COLOR_SUFFIX}]===> " "$@" -} -success() -{ - echo -e "${BRIGHT_GREEN_PREFIX}===> [SUCCESS] <===${COLOR_SUFFIX}\n=> " "$@" -} +# --- make demo (run demo) --- +reset=$(tput sgr0) +bold=$(tput bold) +black=$(tput setaf 0) +red=$(tput setaf 1) +green=$(tput bold; tput setaf 2) +yellow=$(tput bold; tput setaf 3) +blue=$(tput bold; tput setaf 6) +timeout=$(if [ "$(uname)" == "Darwin" ]; then echo "1"; else echo "0.1"; fi) + # Print colors you can use openim::color::print_color() @@ -85,3 +95,57 @@ openim::color::print_color() dim; blink; nobold; under" echo } + +# test functions +openim::color::test() { + echo "Starting the color tests..." + + echo "Testing normal echo without color" + openim::color::echo $COLOR_NORMAL "This is a normal text" + + echo "Testing bold echo" + openim::color::echo $COLOR_BOLD "This is bold text" + + echo "Testing dim echo" + openim::color::echo $COLOR_DIM "This is dim text" + + echo "Testing underlined echo" + openim::color::echo $COLOR_UNDER "This is underlined text" + + echo "Testing italic echo" + openim::color::echo $COLOR_ITALIC "This is italic text" + + echo "Testing red color" + openim::color::echo $COLOR_RED "This is red text" + + echo "Testing green color" + openim::color::echo $COLOR_GREEN "This is green text" + + echo "Testing yellow color" + openim::color::echo $COLOR_YELLOW "This is yellow text" + + echo "Testing blue color" + openim::color::echo $COLOR_BLUE "This is blue text" + + echo "Testing magenta color" + openim::color::echo $COLOR_MAGENTA "This is magenta text" + + echo "Testing cyan color" + openim::color::echo $COLOR_CYAN "This is cyan text" + + echo "Testing black background" + openim::color::echo $COLOR_BBLACK "This is text with black background" + + echo "Testing red background" + openim::color::echo $COLOR_BRED "This is text with red background" + + echo "Testing green background" + openim::color::echo $COLOR_BGREEN "This is text with green background" + + echo "Testing blue background" + openim::color::echo $COLOR_BBLUE "This is text with blue background" + + echo "All tests completed!" +} + +# openim::color::test diff --git a/scripts/lib/golang.sh b/scripts/lib/golang.sh index 0d35e9198..2a537b04c 100755 --- a/scripts/lib/golang.sh +++ b/scripts/lib/golang.sh @@ -13,24 +13,58 @@ # See the License for the specific language governing permissions and # limitations under the License. - -# shellcheck disable=SC2034 # Variables sourced in other scripts. +# The golang package that we are building. +OPENIM_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd -P)" +readonly OPENIM_GO_PACKAGE=github.com/openimsdk/open-im-server # The server platform we are building on. readonly OPENIM_SUPPORTED_SERVER_PLATFORMS=( linux/amd64 linux/arm64 + linux/s390x + linux_mips64 + linux_mips64le + darwin_amd64 + windows_amd64 + linux_amd64 + linux_arm64 + linux_ppc64le ) # If we update this we should also update the set of platforms whose standard -# library is precompiled for in build/build-image/cross/Dockerfile readonly OPENIM_SUPPORTED_CLIENT_PLATFORMS=( linux/amd64 linux/arm64 + linux/s390x + linux/ppc64le + windows/amd64 +) + +# openim chat +readonly OPENIM_CHAT_SUPPORTED_PLATFORMS=( + linux/amd64 + linux/arm64 + linux/s390x + linux/ppc64le + windows/amd64 +) + +# Which platforms we should compile test targets for. +# Not all client platforms need these tests +readonly KUBE_SUPPORTED_TEST_PLATFORMS=( + linux/amd64 + linux/arm64 + linux/s390x + linux/ppc64le + darwin/amd64 + darwin/arm64 + windows/amd64 + windows/arm64 ) # The set of server targets that we are only building for Linux # If you update this list, please also update build/BUILD. +# TODO: Label openim::golang::server_targets() { local targets=( openim-api @@ -54,14 +88,84 @@ IFS=" " read -ra OPENIM_SERVER_TARGETS <<< "$(openim::golang::server_targets)" readonly OPENIM_SERVER_TARGETS readonly OPENIM_SERVER_BINARIES=("${OPENIM_SERVER_TARGETS[@]##*/}") +# TODO: Label +START_SCRIPTS_PATH="${OPENIM_ROOT}/scripts/install/" +openim::golang::start_script_list() { + local targets=( + openim-api.sh + openim-rpc.sh + openim-push.sh + openim-msgtransfer.sh + openim-msggateway.sh + openim-crontask.sh + openim-tools.sh + ) + local result=() + for target in "${targets[@]}"; do + result+=("${START_SCRIPTS_PATH}${target}") + done + + echo "${result[@]}" +} + +# Populate the OPENIM_SERVER_SCRIPT_START_LIST with the full path names of the scripts. +IFS=" " read -ra OPENIM_SERVER_SCRIPT_START_LIST <<< "$(openim::golang::start_script_list)" +readonly OPENIM_SERVER_SCRIPT_START_LIST + +# Extract just the script names from the full paths. +readonly OPENIM_SERVER_SCRIPTARIES=("${OPENIM_SERVER_SCRIPT_START_LIST[@]##*/}") + +openim::golang::check_openim_binaries() { + local missing_binaries=() + for binary in "${OPENIM_SERVER_BINARIES[@]}"; do + if [[ ! -x "${OPENIM_OUTPUT_HOSTBIN}/${binary}" ]]; then + missing_binaries+=("${binary}") + fi + done + + if [[ ${#missing_binaries[@]} -ne 0 ]]; then + echo "The following binaries were not found in ${OPENIM_OUTPUT_HOSTBIN}:" + for missing in "${missing_binaries[@]}"; do + echo " - ${missing}" + done + return 1 + else + echo "All binaries have been installed in ${OPENIM_OUTPUT_HOSTBIN}。" + return 0 + fi +} + +openim::golang::tools_targets() { + local targets=( + yamlfmt + changelog + infra + ncpu + ) + echo "${targets[@]}" +} + +IFS=" " read -ra OPENIM_TOOLS_TARGETS <<< "$(openim::golang::tools_targets)" +readonly OPENIM_TOOLS_TARGETS +readonly OPENIM_TOOLS_BINARIES=("${OPENIM_TOOLS_TARGETS[@]##*/}") + # The set of server targets we build docker images for openim::golang::server_image_targets() { # NOTE: this contains cmd targets for openim::build::get_docker_wrapped_binaries local targets=( - cmd/openim-apiserver - cmd/openim-authz-server - cmd/openim-pump - cmd/openim-watcher + cmd/openim-api + cmd/openim-cmdutils + cmd/openim-crontask + cmd/openim-msggateway + cmd/openim-msgtransfer + cmd/openim-push + cmd/openim-rpc-auth + cmd/openim-rpc-conversation + cmd/openim-rpc-friend + cmd/openim-rpc-group + cmd/openim-rpc-msg + cmd/openim-rpc-third + cmd/openim-rpc-user ) echo "${targets[@]}" } @@ -70,6 +174,8 @@ IFS=" " read -ra OPENIM_SERVER_IMAGE_TARGETS <<< "$(openim::golang::server_image readonly OPENIM_SERVER_IMAGE_TARGETS readonly OPENIM_SERVER_IMAGE_BINARIES=("${OPENIM_SERVER_IMAGE_TARGETS[@]##*/}") +# shellcheck disable=SC2034 # Variables sourced in other scripts. + # ------------ # NOTE: All functions that return lists should use newlines. # bash functions can't return arrays, and spaces are tricky, so newline @@ -87,12 +193,21 @@ openim::golang::dups() { printf "%s\n" "$@" | sort | uniq -d } +# echo "aa: $OPENIM_SERVER_IMAGE_TARGETS" +# echo "aa: $OPENIM_SERVER_IMAGE_BINARIES" + +openim::golang::dups $OPENIM_SERVER_IMAGE_TARGETS +openim::golang::dups $OPENIM_SERVER_IMAGE_BINARIES + # Returns a sorted newline-separated list with duplicated items removed. openim::golang::dedup() { # We use printf to insert newlines, which are required by sort. printf "%s\n" "$@" | sort -u } +# openim::golang::dedup $OPENIM_SERVER_IMAGE_TARGETS +# openim::golang::dedup $OPENIM_SERVER_IMAGE_BINARIES + # Depends on values of user-facing OPENIM_BUILD_PLATFORMS, OPENIM_FASTBUILD, # and OPENIM_BUILDER_OS. # Configures OPENIM_SERVER_PLATFORMS and OPENIM_CLIENT_PLATFORMS, then sets them @@ -175,7 +290,7 @@ EOF local go_version IFS=" " read -ra go_version <<< "$(go version)" local minimum_go_version - minimum_go_version=go1.13.4 + minimum_go_version=go1.18 if [[ "${minimum_go_version}" != $(echo -e "${minimum_go_version}\n${go_version[2]}" | sort -s -t. -k 1,1 -k 2,2n -k 3,3n | head -n1) && "${go_version[2]}" != "devel" ]]; then openim::log::usage_from_stdin < 0 to enable rsync +# compression for build container +OPENIM_RSYNC_COMPRESS="${KUBE_RSYNC_COMPRESS:-0}" + +# Set no_proxy for localhost if behind a proxy, otherwise, +# the connections to localhost in scripts will time out +export no_proxy="127.0.0.1,localhost${no_proxy:+,${no_proxy}}" + +# This is a symlink to binaries for "this platform", e.g. build tools. +export THIS_PLATFORM_BIN="${OPENIM_ROOT}/_output/bin/platforms" +export THIS_PLATFORM_BIN_TOOLS="${OPENIM_ROOT}/_output/bin/tools" + +. $(dirname ${BASH_SOURCE})/color.sh +. $(dirname ${BASH_SOURCE})/util.sh +. $(dirname ${BASH_SOURCE})/logging.sh openim::log::install_errexit +openim::util::ensure-bash-version -source "${OPENIM_ROOT}/scripts/lib/version.sh" -source "${OPENIM_ROOT}/scripts/lib/golang.sh" +. $(dirname ${BASH_SOURCE})/version.sh +. $(dirname ${BASH_SOURCE})/golang.sh +. $(dirname ${BASH_SOURCE})/release.sh +. $(dirname ${BASH_SOURCE})/chat.sh + +OPENIM_OUTPUT_HOSTBIN="${OPENIM_OUTPUT_BINPATH}/$(openim::util::host_platform)" +export OPENIM_OUTPUT_HOSTBIN +OPENIM_OUTPUT_HOSTBIN_TOOLS="${OPENIM_OUTPUT_BINTOOLPATH}/$(openim::util::host_platform)" +export OPENIM_OUTPUT_HOSTBIN_TOOLS + +export OPENIM_NONSERVER_GROUP_VERSIONS + + +# This emulates "readlink -f" which is not available on MacOS X. +# Test: +# T=/tmp/$$.$RANDOM +# mkdir $T +# touch $T/file +# mkdir $T/dir +# ln -s $T/file $T/linkfile +# ln -s $T/dir $T/linkdir +# function testone() { +# X=$(readlink -f $1 2>&1) +# Y=$(kube::readlinkdashf $1 2>&1) +# if [ "$X" != "$Y" ]; then +# echo readlinkdashf $1: expected "$X", got "$Y" +# fi +# } +# testone / +# testone /tmp +# testone $T +# testone $T/file +# testone $T/dir +# testone $T/linkfile +# testone $T/linkdir +# testone $T/nonexistant +# testone $T/linkdir/file +# testone $T/linkdir/dir +# testone $T/linkdir/linkfile +# testone $T/linkdir/linkdir +function openim::readlinkdashf { + # run in a subshell for simpler 'cd' + ( + if [[ -d "${1}" ]]; then # This also catch symlinks to dirs. + cd "${1}" + pwd -P + else + cd "$(dirname "${1}")" + local f + f=$(basename "${1}") + if [[ -L "${f}" ]]; then + readlink "${f}" + else + echo "$(pwd -P)/${f}" + fi + fi + ) +} + +# This emulates "readlink -f" which is not available on MacOS X. +# Test: +# T=/tmp/$$.$RANDOM +# mkdir $T +# touch $T/file +# mkdir $T/dir +# ln -s $T/file $T/linkfile +# ln -s $T/dir $T/linkdir +# function testone() { +# X=$(readlink -f $1 2>&1) +# Y=$(kube::readlinkdashf $1 2>&1) +# if [ "$X" != "$Y" ]; then +# echo readlinkdashf $1: expected "$X", got "$Y" +# fi +# } +# testone / +# testone /tmp +# testone $T +# testone $T/file +# testone $T/dir +# testone $T/linkfile +# testone $T/linkdir +# testone $T/nonexistant +# testone $T/linkdir/file +# testone $T/linkdir/dir +# testone $T/linkdir/linkfile +# testone $T/linkdir/linkdir +function openim::readlinkdashf { + # run in a subshell for simpler 'cd' + ( + if [[ -d "${1}" ]]; then # This also catch symlinks to dirs. + cd "${1}" + pwd -P + else + cd "$(dirname "${1}")" + local f + f=$(basename "${1}") + if [[ -L "${f}" ]]; then + readlink "${f}" + else + echo "$(pwd -P)/${f}" + fi + fi + ) +} + +# This emulates "realpath" which is not available on MacOS X +# Test: +# T=/tmp/$$.$RANDOM +# mkdir $T +# touch $T/file +# mkdir $T/dir +# ln -s $T/file $T/linkfile +# ln -s $T/dir $T/linkdir +# function testone() { +# X=$(realpath $1 2>&1) +# Y=$(kube::realpath $1 2>&1) +# if [ "$X" != "$Y" ]; then +# echo realpath $1: expected "$X", got "$Y" +# fi +# } +# testone / +# testone /tmp +# testone $T +# testone $T/file +# testone $T/dir +# testone $T/linkfile +# testone $T/linkdir +# testone $T/nonexistant +# testone $T/linkdir/file +# testone $T/linkdir/dir +# testone $T/linkdir/linkfile +# testone $T/linkdir/linkdir +openim::realpath() { + if [[ ! -e "${1}" ]]; then + echo "${1}: No such file or directory" >&2 + return 1 + fi + openim::readlinkdashf "${1}" +} + +# Marker function to indicate init.sh has been fully sourced +openim::init::loaded() { + return 0 +} \ No newline at end of file diff --git a/scripts/lib/logging.sh b/scripts/lib/logging.sh index 092db5513..7dc0c0c2a 100755 --- a/scripts/lib/logging.sh +++ b/scripts/lib/logging.sh @@ -13,10 +13,39 @@ # See the License for the specific language governing permissions and # limitations under the License. - # Controls verbosity of the script output and logging. OPENIM_VERBOSE="${OPENIM_VERBOSE:-5}" +# Enable logging by default. Set to false to disable. +ENABLE_LOGGING=true + +# If OPENIM_OUTPUT is not set, set it to the default value +if [[ ! -v OPENIM_OUTPUT ]]; then + OPENIM_OUTPUT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../_output" && pwd -P)" +fi + +# Set the log file path +LOG_FILE="${OPENIM_OUTPUT}/logs/openim_$(date '+%Y%m%d').log" + +if [[ ! -d "${OPENIM_OUTPUT}/logs" ]]; then + mkdir -p "${OPENIM_OUTPUT}/logs" + touch "$LOG_FILE" +fi + +# Define the logging function +function echo_log() { + if $ENABLE_LOGGING; then + echo -e "$@" | tee -a "${LOG_FILE}" + else + echo -e "$@" + fi +} + +# MAX_LOG_SIZE=10485760 # 10MB + +# Clear logs from 5 days ago +# find $OPENIM_OUTPUT_LOGS -type f -name "*.log" -mtime +5 -exec rm -f {} \; + # Handler for when we exit automatically on an error. # Borrowed from https://gist.github.com/ahendrix/7030300 openim::log::errexit() { @@ -58,7 +87,7 @@ openim::log::stack() { local stack_skip=${1:-0} stack_skip=$((stack_skip + 1)) if [[ ${#FUNCNAME[@]} -gt ${stack_skip} ]]; then - echo "Call stack:" >&2 + echo_log "Call stack:" >&2 local i for ((i=1 ; i <= ${#FUNCNAME[@]} - stack_skip ; i++)) do @@ -66,7 +95,7 @@ openim::log::stack() { local source_file=${BASH_SOURCE[${frame_no}]} local source_lineno=${BASH_LINENO[$((frame_no - 1))]} local funcname=${FUNCNAME[${frame_no}]} - echo " ${i}: ${source_file}:${source_lineno} ${funcname}(...)" >&2 + echo_log " ${i}: ${source_file}:${source_lineno} ${funcname}(...)" >&2 done fi } @@ -85,14 +114,14 @@ openim::log::error_exit() { if [[ ${OPENIM_VERBOSE} -ge 4 ]]; then local source_file=${BASH_SOURCE[${stack_skip}]} local source_line=${BASH_LINENO[$((stack_skip - 1))]} - echo "!!! Error in ${source_file}:${source_line}" >&2 + echo_log -e "${COLOR_RED}!!! Error in ${source_file}:${source_line} ${COLOR_SUFFIX}" >&2 [[ -z ${1-} ]] || { - echo " ${1}" >&2 + echo_log " ${1}" >&2 } openim::log::stack ${stack_skip} - echo "Exiting with status ${code}" >&2 + echo_log "Exiting with status ${code}" >&2 fi exit "${code}" @@ -101,21 +130,21 @@ openim::log::error_exit() { # Log an error but keep going. Don't dump the stack or exit. openim::log::error() { timestamp=$(date +"[%m%d %H:%M:%S]") - echo "!!! ${timestamp} ${1-}" >&2 + echo_log "!!! ${timestamp} ${1-}" >&2 shift for message; do - echo " ${message}" >&2 + echo_log " ${message}" >&2 done } # Print an usage message to stderr. The arguments are printed directly. openim::log::usage() { - echo >&2 + echo_log >&2 local message for message; do - echo "${message}" >&2 + echo_log "${message}" >&2 done - echo >&2 + echo_log >&2 } openim::log::usage_from_stdin() { @@ -135,17 +164,18 @@ openim::log::info() { fi for message; do - echo "${message}" + echo_log "${message}" done } # Just like openim::log::info, but no \n, so you can make a progress bar openim::log::progress() { for message; do - echo -e -n "${message}" + echo_log -e -n "${message}" done } +# Print out some info that isn't a top level status line openim::log::info_from_stdin() { local messages=() while read -r line; do @@ -163,9 +193,31 @@ openim::log::status() { fi timestamp=$(date +"[%m%d %H:%M:%S]") - echo "+++ ${timestamp} ${1}" + echo_log "+++ ${timestamp} ${1}" shift for message; do - echo " ${message}" + echo_log " ${message}" done } + +openim::log::success() +{ + local V="${V:-0}" + if [[ ${OPENIM_VERBOSE} < ${V} ]]; then + return + fi + timestamp=$(date +"%m%d %H:%M:%S") + echo_log -e "${COLOR_GREEN}[success ${timestamp}] ${COLOR_SUFFIX}==> " "$@" +} + +function openim::log::test_log() { + echo_log "test log" + openim::log::error "openim::log::error" + openim::log::info "openim::log::info" + openim::log::progress "openim::log::progress" + openim::log::status "openim::log::status" + openim::log::success "openim::log::success" + openim::log::error_exit "openim::log::error_exit" +} + +# openim::log::test_log \ No newline at end of file diff --git a/scripts/lib/release.sh b/scripts/lib/release.sh index a198e1ae6..a3ee9ad13 100755 --- a/scripts/lib/release.sh +++ b/scripts/lib/release.sh @@ -38,6 +38,7 @@ readonly RELEASE_IMAGES="${LOCAL_OUTPUT_ROOT}/release-images" # OpenIM github account info readonly OPENIM_GITHUB_ORG=OpenIMSDK readonly OPENIM_GITHUB_REPO=Open-IM-Server +readonly CHAT_GITHUB_REPO=chat readonly ARTIFACT=openim.tar.gz readonly CHECKSUM=${ARTIFACT}.sha1sum @@ -104,7 +105,7 @@ function openim::release::package_tarballs() { mkdir -p "${RELEASE_TARS}" openim::release::package_src_tarball & openim::release::package_client_tarballs & - openim::release::package_iam_manifests_tarball & + openim::release::package_openim_manifests_tarball & openim::release::package_server_tarballs & openim::util::wait-for-jobs || { openim::log::error "previous tarball phase failed"; return 1; } @@ -143,8 +144,8 @@ function openim::release::package_src_tarball() { -path "${OPENIM_ROOT}"/.config\* -o \ -path "${OPENIM_ROOT}"/.chglog\* -o \ -path "${OPENIM_ROOT}"/.gitlint -o \ - -path "${OPENIM_ROOT}"/.golangci.yml -o \ - -path "${OPENIM_ROOT}"/.goreleaser.yml -o \ + -path "${OPENIM_ROOT}"/scripts/golangci.yml -o \ + -path "${OPENIM_ROOT}"/build/goreleaser.yaml -o \ -path "${OPENIM_ROOT}"/.note.md -o \ -path "${OPENIM_ROOT}"/.todo.md \ \) -prune \ @@ -395,7 +396,7 @@ EOF } # This will pack openim-system manifests files for distros such as COS. -function openim::release::package_iam_manifests_tarball() { +function openim::release::package_openim_manifests_tarball() { openim::log::status "Building tarball: manifests" local src_dir="${OPENIM_ROOT}/deployments" @@ -456,11 +457,6 @@ EOF cp -R "${OPENIM_ROOT}/scripts/release" "${release_stage}/" cat < "${release_stage}/release/get-openim-binaries.sh" #!/usr/bin/env bash - -# Copyright 2020 Lingfei Kong . All rights reserved. -# Use of this source code is governed by a MIT style -# license that can be found in the LICENSE file. - # This file download openim client and server binaries from tencent cos bucket. os=linux arch=amd64 version=${OPENIM_GIT_VERSION} && wget https://${BUCKET}.cos.${REGION}.myqcloud.com/${COS_RELEASE_DIR}/\$version/{openim-client-\$os-\$arch.tar.gz,openim-server-\$os-\$arch.tar.gz} diff --git a/scripts/lib/util.sh b/scripts/lib/util.sh index f9a55d37c..5252f8599 100755 --- a/scripts/lib/util.sh +++ b/scripts/lib/util.sh @@ -13,6 +13,74 @@ # See the License for the specific language governing permissions and # limitations under the License. +# this script is used to check whether the code is formatted by gofmt or not +# +# Usage: source scripts/lib/util.sh +################################################################################ + +# TODO Debug: Just for testing, please comment out +# OPENIM_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/../.. && pwd -P) +# source "${OPENIM_ROOT}/scripts/lib/logging.sh" + +#1、将IP写在一个文件里,比如文件名为hosts_file,一行一个IP地址。 +#2、修改ssh-mutual-trust.sh里面的用户名及密码,默认为root用户及密码123。 +# hosts_file_path="path/to/your/hosts/file" +# openim:util::setup_ssh_key_copy "$hosts_file_path" "root" "123" +function openim:util::setup_ssh_key_copy() { + local hosts_file="$1" + local username="${2:-root}" + local password="${3:-123}" + + local sshkey_file=~/.ssh/id_rsa.pub + + # check sshkey file + if [[ ! -e $sshkey_file ]]; then + expect -c " + spawn ssh-keygen -t rsa + expect \"Enter*\" { send \"\n\"; exp_continue; } + " + fi + + # get hosts list + local hosts=$(awk '/^[^#]/ {print $1}' "${hosts_file}") + + ssh_key_copy() { + local target=$1 + + # delete history + sed -i "/$target/d" ~/.ssh/known_hosts + + # copy key + expect -c " + set timeout 100 + spawn ssh-copy-id $username@$target + expect { + \"yes/no\" { send \"yes\n\"; exp_continue; } + \"*assword\" { send \"$password\n\"; } + \"already exist on the remote system\" { exit 1; } + } + expect eof + " + } + + # auto sshkey pair + for host in $hosts; do + if ! ping -i 0.2 -c 3 -W 1 "$host" > /dev/null 2>&1; then + echo "[ERROR]: Can't connect $host" + continue + fi + + local host_entry=$(awk "/$host/"'{print $1, $2}' /etc/hosts) + if [[ $host_entry ]]; then + local hostaddr=$(echo "$host_entry" | awk '{print $1}') + local hostname=$(echo "$host_entry" | awk '{print $2}') + ssh_key_copy "$hostaddr" + ssh_key_copy "$hostname" + else + ssh_key_copy "$host" + fi + done +} function openim::util::sourced_variable { # Call this function to tell shellcheck that a variable is supposed to @@ -64,7 +132,7 @@ openim::util::wait_for_url() { return 1 } -# Example: openim::util::wait_for_success 120 5 "imctl get nodes|grep localhost" +# Example: openim::util::wait_for_success 120 5 "openimctl get nodes|grep localhost" # arguments: wait time, sleep time, shell command # returns 0 if the shell command get output, 1 otherwise. openim::util::wait_for_success(){ @@ -122,7 +190,7 @@ openim::util::cleanup-temp-dir() { # OPENIM_TEMP openim::util::ensure-temp-dir() { if [[ -z ${OPENIM_TEMP-} ]]; then - OPENIM_TEMP=$(mktemp -d 2>/dev/null || mktemp -d -t iamrnetes.XXXXXX) + OPENIM_TEMP=$(mktemp -d 2>/dev/null || mktemp -d -t openimrnetes.XXXXXX) openim::util::trap_add openim::util::cleanup-temp-dir EXIT fi } @@ -182,6 +250,272 @@ openim::util::host_arch() { echo "${host_arch}" } +# The `openim::util::check_ports` function analyzes the state of processes based on given ports. +# It accepts multiple ports as arguments and prints: +# 1. The state of the process (whether it's running or not). +# 2. The start time of the process if it's running. +# User: +# openim::util::check_ports 8080 8081 8082 +# The function returns a status of 1 if any of the processes is not running. +openim::util::check_ports() { + # An array to collect ports of processes that are not running. + local not_started=() + + # An array to collect information about processes that are running. + local started=() + + openim::log::info "Checking ports: $*" + # Iterate over each given port. + for port in "$@"; do + # Use the `lsof` command to find process information related to the given port. + local info=$(lsof -i :$port -n -P | grep LISTEN || true) + + # If there's no process information, it means the process associated with the port is not running. + if [[ -z $info ]]; then + not_started+=($port) + else + # If there's process information, extract relevant details: + # Process ID, Command Name, and Start Time. + local pid=$(echo $info | awk '{print $2}') + local command=$(echo $info | awk '{print $1}') + local start_time=$(ps -o lstart= -p $pid) + started+=("Port $port - Command: $command, PID: $pid, Start time: $start_time") + fi + done + echo + # Print information about ports whose processes are not running. + if [[ ${#not_started[@]} -ne 0 ]]; then + openim::log::info "### Not started ports:" + for port in "${not_started[@]}"; do + openim::log::error "Port $port is not started." + done + fi + + # Print information about ports whose processes are running. + if [[ ${#started[@]} -ne 0 ]]; then + echo + openim::log::info "### Started ports:" + for info in "${started[@]}"; do + openim::log::info "$info" + done + fi + + # If any of the processes is not running, return a status of 1. + if [[ ${#not_started[@]} -ne 0 ]]; then + echo "++++ OpenIM Log >> cat ${LOG_FILE}" + return 1 + else + openim::log::success "started[@] processes are running." + return 0 + fi +} +# openim::util::check_ports 10002 1004 + +# The `openim::util::check_process_names` function analyzes the state of processes based on given names. +# It accepts multiple process names as arguments and prints: +# 1. The state of the process (whether it's running or not). +# 2. The start time of the process if it's running. +# User: +# openim::util::check_process_names nginx mysql redis +# The function returns a status of 1 if any of the processes is not running. +openim::util::check_process_names() { + # Arrays to collect details of processes + local not_started=() + local started=() + + openim::log::info "Checking processes: $*" + # Iterate over each given process name + for process_name in "$@"; do + # Use `pgrep` to find process IDs related to the given process name + local pids=($(pgrep -f $process_name)) + + # Check if any process IDs were found + if [[ ${#pids[@]} -eq 0 ]]; then + not_started+=($process_name) + else + # If there are PIDs, loop through each one + for pid in "${pids[@]}"; do + local command=$(ps -p $pid -o cmd=) + local start_time=$(ps -p $pid -o lstart=) + local port=$(ss -ltnp 2>/dev/null | grep $pid | awk '{print $4}' | cut -d ':' -f2) + + # Check if port information was found for the PID + if [[ -z $port ]]; then + port="N/A" + fi + + started+=("Process $process_name - Command: $command, PID: $pid, Port: $port, Start time: $start_time") + done + fi + done + + # Print information + if [[ ${#not_started[@]} -ne 0 ]]; then + openim::log::info "Not started processes:" + for process_name in "${not_started[@]}"; do + openim::log::error "Process $process_name is not started." + done + fi + + if [[ ${#started[@]} -ne 0 ]]; then + echo + openim::log::info "Started processes:" + for info in "${started[@]}"; do + openim::log::info "$info" + done + fi + + # Return status + if [[ ${#not_started[@]} -ne 0 ]]; then + echo "++++ OpenIM Log >> cat ${LOG_FILE}" + return 1 + else + openim::log::success "All processes are running." + return 0 + fi +} +# openim::util::check_process_names docker-pr + +# The `openim::util::stop_services_on_ports` function stops services running on specified ports. +# It accepts multiple ports as arguments and performs the following: +# 1. Attempts to stop any services running on the specified ports. +# 2. Prints details of services successfully stopped and those that failed to stop. +# Usage: +# openim::util::stop_services_on_ports 8080 8081 8082 +# The function returns a status of 1 if any service couldn't be stopped. +openim::util::stop_services_on_ports() { + # An array to collect ports of processes that couldn't be stopped. + local not_stopped=() + + # An array to collect information about processes that were stopped. + local stopped=() + + openim::log::info "Stopping services on ports: $*" + # Iterate over each given port. + for port in "$@"; do + # Use the `lsof` command to find process information related to the given port. + info=$(lsof -i :$port -n -P | grep LISTEN || true) + + # If there's process information, it means the process associated with the port is running. + if [[ -n $info ]]; then + # Extract the Process ID. + while read -r line; do + local pid=$(echo $line | awk '{print $2}') + + # Try to stop the service by killing its process. + if kill -TERM $pid; then + stopped+=($port) + else + not_stopped+=($port) + fi + done <<< "$info" + fi + done + + # Print information about ports whose processes couldn't be stopped. + if [[ ${#not_stopped[@]} -ne 0 ]]; then + openim::log::info "Ports that couldn't be stopped:" + for port in "${not_stopped[@]}"; do + openim::log::status "Failed to stop service on port $port." + done + fi + + # Print information about ports whose processes were successfully stopped. + if [[ ${#stopped[@]} -ne 0 ]]; then + echo + openim::log::info "Stopped services on ports:" + for port in "${stopped[@]}"; do + openim::log::info "Successfully stopped service on port $port." + done + fi + + # If any of the processes couldn't be stopped, return a status of 1. + if [[ ${#not_stopped[@]} -ne 0 ]]; then + return 1 + else + openim::log::success "All specified services were stopped." + return 0 + fi +} +# nc -l -p 12345 +# nc -l -p 123456 +# ps -ef | grep "nc -l" +# openim::util::stop_services_on_ports 1234 12345 + + +# The `openim::util::stop_services_with_name` function stops services with specified names. +# It accepts multiple service names as arguments and performs the following: +# 1. Attempts to stop any services with the specified names. +# 2. Prints details of services successfully stopped and those that failed to stop. +# Usage: +# openim::util::stop_services_with_name nginx apache +# The function returns a status of 1 if any service couldn't be stopped. +openim::util::stop_services_with_name() { + # An array to collect names of processes that couldn't be stopped. + local not_stopped=() + + # An array to collect information about processes that were stopped. + local stopped=() + + openim::log::info "Stopping services with names: $*" + # Iterate over each given service name. + for server_name in "$@"; do + # Use the `pgrep` command to find process IDs related to the given service name. + local pids=$(pgrep -f "$server_name") + + # If no process was found with the name, add it to the not_stopped list + if [[ -z $pids ]]; then + not_stopped+=("$server_name") + continue + fi + local stopped_this_time=false + for pid in $pids; do + + # Exclude the PID of the current script + if [[ "$pid" == "$$" ]]; then + continue + fi + + # If there's a Process ID, it means the service with the name is running. + if [[ -n $pid ]]; then + # Try to stop the service by killing its process. + if kill -TERM $pid 2>/dev/null; then + stopped_this_time=true + fi + fi + done + + if $stopped_this_time; then + stopped+=("$server_name") + else + not_stopped+=("$server_name") + fi + done + + # Print information about services whose processes couldn't be stopped. + if [[ ${#not_stopped[@]} -ne 0 ]]; then + openim::log::info "Services that couldn't be stopped:" + for name in "${not_stopped[@]}"; do + openim::log::status "Failed to stop the $name service." + done + fi + + # Print information about services whose processes were successfully stopped. + if [[ ${#stopped[@]} -ne 0 ]]; then + echo + openim::log::info "Stopped services:" + for name in "${stopped[@]}"; do + openim::log::info "Successfully stopped the $name service." + done + fi + + openim::log::success "All specified services were stopped." +} +# sleep 333333& +# sleep 444444& +# ps -ef | grep "sleep" +# openim::util::stop_services_with_name "sleep 333333" "sleep 444444" + # This figures out the host platform without relying on golang. We need this as # we don't want a golang install to be a prerequisite to building yet we need # this info to figure out where the final binaries are placed. @@ -213,14 +547,14 @@ openim::util::find-binary() { openim::util::find-binary-for-platform "$1" "$(openim::util::host_platform)" } -# Run all known doc generators (today gendocs and genman for imctl) +# Run all known doc generators (today gendocs and genman for openimctl) # $1 is the directory to put those generated documents openim::util::gen-docs() { local dest="$1" # Find binary gendocs=$(openim::util::find-binary "gendocs") - geniamdocs=$(openim::util::find-binary "geniamdocs") + genopenimdocs=$(openim::util::find-binary "genopenimdocs") genman=$(openim::util::find-binary "genman") genyaml=$(openim::util::find-binary "genyaml") genfeddocs=$(openim::util::find-binary "genfeddocs") @@ -229,24 +563,24 @@ openim::util::gen-docs() { # least from k/k tree), remove it completely. openim::util::sourced_variable "${genfeddocs}" - mkdir -p "${dest}/docs/guide/en-US/cmd/imctl/" - "${gendocs}" "${dest}/docs/guide/en-US/cmd/imctl/" + mkdir -p "${dest}/docs/guide/en-US/cmd/openimctl/" + "${gendocs}" "${dest}/docs/guide/en-US/cmd/openimctl/" mkdir -p "${dest}/docs/guide/en-US/cmd/" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-api" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-cmdutils" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-crontask" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-msggateway" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-msgtransfer" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-push" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-auth" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-conversation" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-friend" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-group" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-msg" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-third" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-user" - "${geniamdocs}" "${dest}/docs/guide/en-US/cmd/imctl" "imctl" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-api" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-cmdutils" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-crontask" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-msggateway" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-msgtransfer" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-push" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-auth" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-conversation" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-friend" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-group" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-msg" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-third" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/" "openim-rpc-user" + "${genopenimdocs}" "${dest}/docs/guide/en-US/cmd/openimctl" "openimctl" mkdir -p "${dest}/docs/man/man1/" "${genman}" "${dest}/docs/man/man1/" "openim-api" @@ -263,8 +597,8 @@ openim::util::gen-docs() { "${genman}" "${dest}/docs/man/man1/" "openim-rpc-third" "${genman}" "${dest}/docs/man/man1/" "openim-rpc-user" - mkdir -p "${dest}/docs/guide/en-US/yaml/imctl/" - "${genyaml}" "${dest}/docs/guide/en-US/yaml/imct/" + mkdir -p "${dest}/docs/guide/en-US/yaml/openimctl/" + "${genyaml}" "${dest}/docs/guide/en-US/yaml/openimctl/" # create the list of generated files pushd "${dest}" > /dev/null || return 1 @@ -290,7 +624,7 @@ openim::util::remove-gen-docs() { # repo, e.g. "upstream" or "origin". openim::util::git_upstream_remote_name() { git remote -v | grep fetch |\ - grep -E 'github.com[/:]marmotedu/openim|marmotedu.io/openim' |\ + grep -E 'github.com[/:]OpenIMSDK/Open-IM-Server|openim.cc/server' |\ head -n 1 | awk '{print $1}' } @@ -455,8 +789,8 @@ function openim::util::create_serving_certkey { EOF } -# creates a self-contained iamconfig: args are sudo, dest-dir, ca file, host, port, client id, token(optional) -function openim::util::write_client_iamconfig { +# creates a self-contained openimconfig: args are sudo, dest-dir, ca file, host, port, client id, token(optional) +function openim::util::write_client_openimconfig { local sudo=$1 local dest_dir=$2 local ca_file=$3 @@ -464,7 +798,7 @@ function openim::util::write_client_iamconfig { local api_port=$5 local client_id=$6 local token=${7:-} - cat < /dev/null + cat < /dev/null apiVersion: v1 kind: Config clusters: @@ -486,12 +820,12 @@ contexts: current-context: local-up-cluster EOF - # flatten the iamconfig files to make them self contained + # flatten the openimconfig files to make them self contained username=$(whoami) ${sudo} /usr/bin/env bash -e < "/tmp/${client_id}.iamconfig" - mv -f "/tmp/${client_id}.iamconfig" "${dest_dir}/${client_id}.iamconfig" - chown ${username} "${dest_dir}/${client_id}.iamconfig" + $(openim::util::find-binary openimctl) --openimconfig="${dest_dir}/${client_id}.openimconfig" config view --minify --flatten > "/tmp/${client_id}.openimconfig" + mv -f "/tmp/${client_id}.openimconfig" "${dest_dir}/${client_id}.openimconfig" + chown ${username} "${dest_dir}/${client_id}.openimconfig" EOF } @@ -545,6 +879,29 @@ function openim::util::join { echo "$*" } +# Function: openim::util::list-to-string +# Description: Converts a list to a string, removing spaces, brackets, and commas. +# Example input: [1002 3 , 2 32 3 , 3 434 ,] +# Example output: 10023 2323 3434 +# Example usage: +# result=$(openim::util::list-to-string "[10023, 2323, 3434]") +# echo $result +function openim::util::list-to-string() { + # Capture all arguments into a single string + ports_list="$*" + + # Use sed for transformations: + # 1. Remove spaces + # 2. Replace commas with spaces + # 3. Remove opening and closing brackets + ports_array=$(echo "$ports_list" | sed 's/ //g; s/,/ /g; s/^\[\(.*\)\]$/\1/') + + # For external use, we might want to echo the result so that it can be captured by callers + echo "$ports_array" +} +# MSG_GATEWAY_PROM_PORTS=$(openim::util::list-to-string "10023, 2323, 34 34") +# echo ${MSG_GATEWAY_PROM_PORTS} + # Downloads cfssl/cfssljson/cfssl-certinfo into $1 directory if they do not already exist in PATH # # Assumed vars: @@ -616,6 +973,47 @@ function openim::util::ensure-cfssl { popd > /dev/null || return 1 } +function openim::util::ensure-docker-buildx { + # podman returns 0 on `docker buildx version`, docker on `docker buildx`. One of them must succeed. + if docker buildx version >/dev/null 2>&1 || docker buildx >/dev/null 2>&1; then + return 0 + else + echo "ERROR: docker buildx not available. Docker 19.03 or higher is required with experimental features enabled" + exit 1 + fi +} + +# openim::util::ensure-bash-version +# Check if we are using a supported bash version +# +function openim::util::ensure-bash-version { + # shellcheck disable=SC2004 + if ((${BASH_VERSINFO[0]}<4)) || ( ((${BASH_VERSINFO[0]}==4)) && ((${BASH_VERSINFO[1]}<2)) ); then + echo "ERROR: This script requires a minimum bash version of 4.2, but got version of ${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]}" + if [ "$(uname)" = 'Darwin' ]; then + echo "On macOS with homebrew 'brew install bash' is sufficient." + fi + exit 1 + fi +} + +# openim::util::ensure-install-nginx +# Check if nginx is installed +# +function openim::util::ensure-install-nginx { + if ! command -v nginx &>/dev/null; then + echo "ERROR: nginx not found. Please install nginx." + exit 1 + fi + + for port in 80 + do + if echo |telnet 127.0.0.1 $port 2>&1|grep refused &>/dev/null;then + exit 1 + fi + done +} + # openim::util::ensure-gnu-sed # Determines which sed binary is gnu-sed on linux/darwin # @@ -624,7 +1022,7 @@ function openim::util::ensure-cfssl { # function openim::util::ensure-gnu-sed { # NOTE: the echo below is a workaround to ensure sed is executed before the grep. - # see: https://github.com/iamrnetes/iamrnetes/issues/87251 + # see: https://github.com/openimrnetes/openimrnetes/issues/87251 sed_help="$(LANG=C sed --help 2>&1 || true)" if echo "${sed_help}" | grep -q "GNU\|BusyBox"; then SED="sed" @@ -637,6 +1035,26 @@ function openim::util::ensure-gnu-sed { openim::util::sourced_variable "${SED}" } +# openim::util::ensure-gnu-date +# Determines which date binary is gnu-date on linux/darwin +# +# Sets: +# DATE: The name of the gnu-date binary +# +function openim::util::ensure-gnu-date { + # NOTE: the echo below is a workaround to ensure date is executed before the grep. + date_help="$(LANG=C date --help 2>&1 || true)" + if echo "${date_help}" | grep -q "GNU\|BusyBox"; then + DATE="date" + elif command -v gdate &>/dev/null; then + DATE="gdate" + else + openim::log::error "Failed to find GNU date as date or gdate. If you are on Mac: brew install coreutils." >&2 + return 1 + fi + openim::util::sourced_variable "${DATE}" +} + # openim::util::check-file-in-alphabetical-order # Check that the file is in alphabetical order # @@ -710,22 +1128,155 @@ fi # ex: ts=2 sw=2 et filetype=sh +function openim::util::desc() { + openim::util:run::maybe_first_prompt + rate=25 + if [ -n "$DEMO_RUN_FAST" ]; then + rate=1000 + fi + echo "$blue# $@$reset" | pv -qL $rate + openim::util:run::prompt +} -# input: [10023, 2323, 3434] -# output: 10023 2323 3434 +function openim::util:run::prompt() { + echo -n "$yellow\$ $reset" +} -# Function function: Converts a list to a string, removing Spaces and parentheses -function list_to_string() { - ports_list=$* # 获取传入的参数列表 - sub_s1=$(echo $ports_list | sed 's/ //g') # 去除空格 - sub_s2=${sub_s1//,/ } # 将逗号替换为空格 - sub_s3=${sub_s2#*[} # 去除左括号及其之前的内容 - sub_s4=${sub_s3%]*} # 去除右括号及其之后的内容 - ports_array=$sub_s4 # 将处理后的字符串赋值给变量 ports_array +started="" +function openim::util:run::maybe_first_prompt() { + if [ -z "$started" ]; then + openim::util:run::prompt + started=true + fi +} + +# After a `run` this variable will hold the stdout of the command that was run. +# If the command was interactive, this will likely be garbage. +DEMO_RUN_STDOUT="" + +function openim::util::run() { + openim::util:run::maybe_first_prompt + rate=25 + if [ -n "$DEMO_RUN_FAST" ]; then + rate=1000 + fi + echo "$green$1$reset" | pv -qL $rate + if [ -n "$DEMO_RUN_FAST" ]; then + sleep 0.5 + fi + OFILE="$(mktemp -t $(basename $0).XXXXXX)" + if [ "$(uname)" == "Darwin" ]; then + script -q "$OFILE" $1 + else + script -eq -c "$1" -f "$OFILE" + fi + r=$? + read -d '' -t "${timeout}" -n 10000 # clear stdin + openim::util:run::prompt + if [ -z "$DEMO_AUTO_RUN" ]; then + read -s + fi + DEMO_RUN_STDOUT="$(tail -n +2 $OFILE | sed 's/\r//g')" + return $r +} + +function openim::util::run::relative() { + for arg; do + echo "$(realpath $(dirname $(which $0)))/$arg" | sed "s|$(realpath $(pwd))|.|" + done +} + +# This function retrieves the IP address of the current server. +# It primarily uses the `curl` command to fetch the public IP address from ifconfig.me. +# If curl or the service is not available, it falls back +# to the internal IP address provided by the hostname command. +# TODO: If a delay is found, the delay needs to be addressed +function openim::util::get_server_ip() { + # Check if the 'curl' command is available + if command -v curl &> /dev/null; then + # Try to retrieve the public IP address using curl and ifconfig.me + IP=$(dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | sed 's/"//g' | tr -d '\n') + + # Check if IP retrieval was successful + if [[ -z "$IP" ]]; then + # If not, get the internal IP address + IP=$(ip addr show | grep 'inet ' | grep -v 127.0.0.1 | awk '{print $2}' | cut -d'/' -f1 | head -n 1) + fi + else + # If curl is not available, get the internal IP address + IP=$(ip addr show | grep 'inet ' | grep -v 127.0.0.1 | awk '{print $2}' | cut -d'/' -f1 | head -n 1) + fi + + # Return the fetched IP address + echo "$IP" +} + +function openim::util::onCtrlC() { + kill -9 "${do_sth_pid}" "${progress_pid}" "${countdown_pid}" + echo + echo 'Ctrl+C is captured' + exit 1 } # Function Function: Remove Spaces in the string -function remove_space() { +function openim::util::remove_space() { value=$* # 获取传入的参数 result=$(echo $value | sed 's/ //g') # 去除空格 } + +function openim::util::gencpu() { + # Check the system type + system_type=$(uname) + + if [[ "$system_type" == "Darwin" ]]; then + # macOS (using sysctl) + cpu_count=$(sysctl -n hw.ncpu) + elif [[ "$system_type" == "Linux" ]]; then + # Linux (using lscpu) + cpu_count=$(lscpu --parse | grep -E '^([^#].*,){3}[^#]' | sort -u | wc -l) + else + echo "Unsupported operating system: $system_type" + exit 1 + fi + echo $cpu_count +} + +function openim::util::gen_os_arch() { + # Get the current operating system and architecture + OS=$(uname -s | tr '[:upper:]' '[:lower:]') + ARCH=$(uname -m) + + # Select the repository home directory based on the operating system and architecture + if [[ "$OS" == "darwin" ]]; then + if [[ "$ARCH" == "x86_64" ]]; then + REPO_DIR="darwin/amd64" + else + REPO_DIR="darwin/386" + fi + elif [[ "$OS" == "linux" ]]; then + if [[ "$ARCH" == "x86_64" ]]; then + REPO_DIR="linux/amd64" + elif [[ "$ARCH" == "arm64" ]]; then + REPO_DIR="linux/arm64" + elif [[ "$ARCH" == "mips64" ]]; then + REPO_DIR="linux/mips64" + elif [[ "$ARCH" == "mips64le" ]]; then + REPO_DIR="linux/mips64le" + elif [[ "$ARCH" == "ppc64le" ]]; then + REPO_DIR="linux/ppc64le" + elif [[ "$ARCH" == "s390x" ]]; then + REPO_DIR="linux/s390x" + else + REPO_DIR="linux/386" + fi + elif [[ "$OS" == "windows" ]]; then + if [[ "$ARCH" == "x86_64" ]]; then + REPO_DIR="windows/amd64" + else + REPO_DIR="windows/386" + fi + else + echo -e "${RED_PREFIX}Unsupported OS: $OS${COLOR_SUFFIX}" + exit 1 + fi +} diff --git a/scripts/lib/version.sh b/scripts/lib/version.sh index 65f9bb353..04eb89b09 100755 --- a/scripts/lib/version.sh +++ b/scripts/lib/version.sh @@ -12,7 +12,6 @@ # 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. - # ----------------------------------------------------------------------------- # Version management helpers. These functions help to set, save and load the diff --git a/scripts/enterprise/function.sh b/scripts/list-feature-tests.sh similarity index 67% rename from scripts/enterprise/function.sh rename to scripts/list-feature-tests.sh index 8b5cb0b2b..438474bae 100755 --- a/scripts/enterprise/function.sh +++ b/scripts/list-feature-tests.sh @@ -13,17 +13,14 @@ # See the License for the specific language governing permissions and # limitations under the License. -#input:[10023,2323,3434] -#output:10023 2323 3434 -list_to_string(){ - ports_list=$* - sub_s1=`echo $ports_list | sed 's/ //g'` - sub_s2=${sub_s1//,/ } - sub_s3=${sub_s2#*[} - sub_s4=${sub_s3%]*} - ports_array=$sub_s4 -} -remove_space(){ - value=$* - result=`echo $value | sed 's/ //g'` -} \ No newline at end of file + +# This script lists all of the [Feature:.+] tests in our e2e suite. +# +# Usage: `scripts/list-feature-tests.sh`. + +set -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +grep "\[Feature:\w+\]" "${OPENIM_ROOT}"/test/e2e/**/*.go -Eoh | LC_ALL=C sort -u \ No newline at end of file diff --git a/scripts/make-rules/common.mk b/scripts/make-rules/common.mk index 0da5af561..1473963df 100644 --- a/scripts/make-rules/common.mk +++ b/scripts/make-rules/common.mk @@ -48,10 +48,16 @@ endif # BIN_TOOLS_DIR: Directory where executable files are stored. ifeq ($(origin BIN_TOOLS_DIR),undefined) -BIN_TOOLS_DIR := $(OUTPUT_DIR)/bin-tools +BIN_TOOLS_DIR := $(BIN_DIR)/tools $(shell mkdir -p $(BIN_TOOLS_DIR)) endif +# LOGS_DIR: Directory where log files are stored. +ifeq ($(origin LOGS_DIR),undefined) +LOGS_DIR := $(OUTPUT_DIR)/logs +$(shell mkdir -p $(LOGS_DIR)) +endif + # TOOLS_DIR: The directory where tools are stored for build and testing. ifeq ($(origin TOOLS_DIR),undefined) TOOLS_DIR := $(OUTPUT_DIR)/tools @@ -65,7 +71,7 @@ $(shell mkdir -p $(TMP_DIR)) endif ifeq ($(origin VERSION), undefined) -# VERSION := $(shell git describe --abbrev=0 --dirty --always --tags | sed 's/-/./g') #v2.3.3.dirty +# VERSION := $(shell git describe --tags --always --match='v*') # git describe --tags --always --match="v*" --dirty VERSION := $(shell git describe --tags --always --match="v*" --dirty | sed 's/-/./g') #v2.3.3.631.g00abdc9b.dirty # v2.3.3: git tag @@ -94,7 +100,7 @@ endif # The OS must be linux when building docker images # PLATFORMS ?= linux_amd64 linux_arm64 # The OS can be linux/windows/darwin when building binaries -PLATFORMS ?= linux_s390x linux_mips64 linux_mips64le darwin_amd64 windows_amd64 linux_amd64 linux_arm64 linux_ppc64le +PLATFORMS ?= linux_s390x linux_mips64 linux_mips64le darwin_amd64 windows_amd64 linux_amd64 linux_arm64 linux_ppc64le # wasip1_wasm # only support linux GOOS=linux @@ -126,7 +132,7 @@ FIND := find . ! -path './utils/*' ! -path './vendor/*' ! -path './third_party/* XARGS := xargs -r --no-run-if-empty # Linux command settings-CODE DIRS Copyright -CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/config $(ROOT_DIR)/db $(ROOT_DIR)/.docker-compose_cfg $(ROOT_DIR)/internal $(ROOT_DIR)/scripts $(ROOT_DIR)/test $(ROOT_DIR)/.github $(ROOT_DIR)/build $(ROOT_DIR)/build $(ROOT_DIR)/deployments +CODE_DIRS := $(ROOT_DIR)/pkg $(ROOT_DIR)/cmd $(ROOT_DIR)/config $(ROOT_DIR)/.docker-compose_cfg $(ROOT_DIR)/internal $(ROOT_DIR)/scripts $(ROOT_DIR)/test $(ROOT_DIR)/.github $(ROOT_DIR)/build $(ROOT_DIR)/tools $(ROOT_DIR)/deployments FINDS := find $(CODE_DIRS) # Makefile settings: Select different behaviors by determining whether V option is set diff --git a/scripts/make-rules/copyright.mk b/scripts/make-rules/copyright.mk index 2b7a04082..18b4dd709 100644 --- a/scripts/make-rules/copyright.mk +++ b/scripts/make-rules/copyright.mk @@ -17,7 +17,7 @@ # Makefile helper functions for copyright # -LICENSE_TEMPLATE ?= $(ROOT_DIR)/scripts/LICENSE/LICENSE_TEMPLATES +LICENSE_TEMPLATE ?= $(ROOT_DIR)/scripts/template/LICENSE_TEMPLATES ## copyright.verify: Validate boilerplate headers for assign files .PHONY: copyright.verify diff --git a/scripts/make-rules/gen.mk b/scripts/make-rules/gen.mk index 8306c1756..60bfdd47a 100644 --- a/scripts/make-rules/gen.mk +++ b/scripts/make-rules/gen.mk @@ -22,38 +22,52 @@ # Makefile helper functions for generate necessary files # +## gen.init: Initialize openim server project ✨ +.PHONY: gen.init +gen.init: + @echo "===========> Initializing openim server project" + @${ROOT_DIR}/scripts/init-config.sh + +## gen.run: Generate necessary files and docs ✨ .PHONY: gen.run #gen.run: gen.errcode gen.docgo gen.run: gen.clean gen.errcode gen.docgo.doc +## gen.errcode: Generate necessary files and docs ✨ .PHONY: gen.errcode gen.errcode: gen.errcode.code gen.errcode.doc +## gen.errcode.code: Generate openim error code go source files ✨ .PHONY: gen.errcode.code gen.errcode.code: tools.verify.codegen @echo "===========> Generating openim error code go source files" @codegen -type=int ${ROOT_DIR}/internal/pkg/code +## gen.errcode.doc: Generate openim error code markdown documentation ✨ .PHONY: gen.errcode.doc gen.errcode.doc: tools.verify.codegen @echo "===========> Generating error code markdown documentation" @codegen -type=int -doc \ -output ${ROOT_DIR}/docs/guide/zh-CN/api/error_code_generated.md ${ROOT_DIR}/internal/pkg/code +## gen.docgo: Generate missing doc.go for go packages ✨ .PHONY: gen.ca.% gen.ca.%: $(eval CA := $(word 1,$(subst ., ,$*))) @echo "===========> Generating CA files for $(CA)" @${ROOT_DIR}/scripts/gencerts.sh generate-openim-cert $(OUTPUT_DIR)/cert $(CA) +## gen.ca: Generate CA files for all certificates ✨ .PHONY: gen.ca gen.ca: $(addprefix gen.ca., $(CERTIFICATES)) +## gen.docgo: Generate missing doc.go for go packages ✨ .PHONY: gen.docgo.doc gen.docgo.doc: @echo "===========> Generating missing doc.go for go packages" @${ROOT_DIR}/scripts/gendoc.sh +## gen.docgo.check: Check if there are untracked doc.go files ✨ .PHONY: gen.docgo.check gen.docgo.check: gen.docgo.doc @n="$$(git ls-files --others '*/doc.go' | wc -l)"; \ @@ -63,14 +77,17 @@ gen.docgo.check: gen.docgo.doc false ; \ fi +## gen.docgo.add: Add untracked doc.go files to git index ✨ .PHONY: gen.docgo.add gen.docgo.add: @git ls-files --others '*/doc.go' | $(XARGS) -- git add +## gen.docgo: Generate missing doc.go for go packages ✨ .PHONY: gen.defaultconfigs gen.defaultconfigs: @${ROOT_DIR}/scripts/gen_default_config.sh +## gen.docgo: Generate missing doc.go for go packages ✨ .PHONY: gen.clean gen.clean: @rm -rf ./api/client/{clientset,informers,listers} diff --git a/scripts/make-rules/golang.mk b/scripts/make-rules/golang.mk index f57c77bc1..4aa3b7e3a 100644 --- a/scripts/make-rules/golang.mk +++ b/scripts/make-rules/golang.mk @@ -17,7 +17,7 @@ # GO := go -GO_SUPPORTED_VERSIONS ?= 1.18|1.19|1.20 +GO_SUPPORTED_VERSIONS ?= 1.18|1.19|1.20|1.21 GO_LDFLAGS += -X $(VERSION_PACKAGE).gitVersion=$(GIT_TAG) \ -X $(VERSION_PACKAGE).gitCommit=$(GIT_COMMIT) \ @@ -45,7 +45,7 @@ ifeq ($(origin GOBIN), undefined) endif # COMMANDS is Specify all files under ${ROOT_DIR}/cmd/ and ${ROOT_DIR}/tools/ except those ending in.md -COMMANDS ?= $(filter-out %.md, $(wildcard ${ROOT_DIR}/cmd/* ${ROOT_DIR}/tools/*)) +COMMANDS ?= $(filter-out %.md, $(wildcard ${ROOT_DIR}/cmd/* ${ROOT_DIR}/tools/* ${ROOT_DIR}/cmd/openim-rpc/*)) ifeq (${COMMANDS},) $(error Could not determine COMMANDS, set ROOT_DIR or run in source dir) endif @@ -101,6 +101,24 @@ EXCLUDE_TESTS=github.com/OpenIMSDK/Open-IM-Server/test github.com/OpenIMSDK/Open go.build: go.build.verify $(addprefix go.build., $(addprefix $(PLATFORM)., $(BINS))) @echo "===========> Building binary $(BINS) $(VERSION) for $(PLATFORM)" +## go.start: Start openim +.PHONY: go.start +go.start: + @echo "===========> Starting openim" + @$(ROOT_DIR)/scripts/start-all.sh + +## go.stop: Stop openim +.PHONY: go.stop +go.stop: + @echo "===========> Stopping openim" + @$(ROOT_DIR)/scripts/stop-all.sh + +## go.check: Check openim +.PHONY: go.check +go.check: + @echo "===========> Checking openim" + @$(ROOT_DIR)/scripts/check-all.sh + ## go.build.verify: Verify that a suitable version of Go exists .PHONY: go.build.verify go.build.verify: @@ -116,23 +134,21 @@ go.build.%: $(eval ARCH := $(word 2,$(subst _, ,$(PLATFORM)))) @echo "=====> COMMAND=$(COMMAND)" @echo "=====> PLATFORM=$(PLATFORM)" - @echo "=====> BIN_DIR=$(BIN_DIR)" @echo "===========> Building binary $(COMMAND) $(VERSION) for $(OS)_$(ARCH)" @mkdir -p $(BIN_DIR)/platforms/$(OS)/$(ARCH) @if [ "$(COMMAND)" == "openim-sdk-core" ]; then \ echo "===========> DEBUG: OpenIM-SDK-Core It is no longer supported for openim-server $(COMMAND)"; \ - elif [ "$(COMMAND)" == "openim-rpc" ]; then \ - for d in $(wildcard $(ROOT_DIR)/cmd/openim-rpc/*); do \ - cd $${d} && CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o \ - $(BIN_DIR)/platforms/$(OS)/$(ARCH)/$$(basename $${d})$(GO_OUT_EXT) $${d}/main.go; \ - done; \ + elif [ -d $(ROOT_DIR)/cmd/openim-rpc/$(COMMAND) ]; then \ + CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o \ + $(BIN_DIR)/platforms/$(OS)/$(ARCH)/$(COMMAND)$(GO_OUT_EXT) $(ROOT_DIR)/cmd/openim-rpc/$(COMMAND)/main.go; \ else \ if [ -f $(ROOT_DIR)/cmd/$(COMMAND)/main.go ]; then \ CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o \ $(BIN_DIR)/platforms/$(OS)/$(ARCH)/$(COMMAND)$(GO_OUT_EXT) $(ROOT_DIR)/cmd/$(COMMAND)/main.go; \ - elif [ -f $(ROOT_DIR)/tools/$(COMMAND)/main.go ]; then \ + elif [ -f $(ROOT_DIR)/tools/$(COMMAND)/$(COMMAND).go ]; then \ CGO_ENABLED=0 GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(GO_BUILD_FLAGS) -o \ - $(BIN_TOOLS_DIR)/platforms/$(OS)/$(ARCH)/$(COMMAND)$(GO_OUT_EXT) $(ROOT_DIR)/tools/$(COMMAND)/main.go; \ + $(BIN_TOOLS_DIR)/$(OS)/$(ARCH)/$(COMMAND)$(GO_OUT_EXT) $(ROOT_DIR)/tools/$(COMMAND)/$(COMMAND).go; \ + chmod +x $(BIN_TOOLS_DIR)/$(OS)/$(ARCH)/$(COMMAND)$(GO_OUT_EXT); \ fi \ fi @@ -140,13 +156,7 @@ go.build.%: .PHONY: go.install go.install: @echo "===========> Installing deployment openim" - @$(ROOT_DIR)/scripts/install_im_server.sh - -## go.check: Check OpenIM deployment -.PHONY: go.check -go.check: - @echo "===========> Checking OpenIM deployment" - @$(ROOT_DIR)/scripts/check_all.sh + @$(ROOT_DIR)/scripts/install-im-server.sh ## go.multiarch: Build multi-arch binaries .PHONY: go.build.multiarch @@ -156,13 +166,19 @@ go.build.multiarch: go.build.verify $(foreach p,$(PLATFORMS),$(addprefix go.buil .PHONY: go.lint go.lint: tools.verify.golangci-lint @echo "===========> Run golangci to lint source codes" - @$(TOOLS_DIR)/golangci-lint run --color always -c $(ROOT_DIR)/.golangci.yml $(ROOT_DIR)/... + @$(TOOLS_DIR)/golangci-lint run --color always -c $(ROOT_DIR)/scripts/golangci.yml $(ROOT_DIR)/... ## go.test: Run unit test .PHONY: go.test go.test: @$(GO) test ./... +## go.demo: Run demo +.PHONY: go.demo +go.demo: + @echo "===========> Run demo" + @$(ROOT_DIR)/scripts/demo.sh + ## go.test.junit-report: Run unit test .PHONY: go.test.junit-report go.test.junit-report: tools.verify.go-junit-report @@ -189,11 +205,23 @@ go.format: tools.verify.golines tools.verify.goimports @$(FIND) -type f -name '*.go' -not -name '*pb*' | $(XARGS) $(TOOLS_DIR)/golines -w --max-len=200 --reformat-tags --shorten-comments --ignore-generated . @$(GO) mod edit -fmt -## imports: task to automatically handle import packages in Go files using goimports tool +## go.imports: task to automatically handle import packages in Go files using goimports tool .PHONY: go.imports go.imports: tools.verify.goimports @$(TOOLS_DIR)/goimports -l -w $(SRC) +## go.verify: execute all verity scripts. +.PHONY: go.verify +go.verify: + @echo "Starting verification..." + @scripts_list=$$(find $(ROOT_DIR)/scripts -type f -name 'verify-*' | sort); \ + for script in $$scripts_list; do \ + echo "Executing $$script..."; \ + $$script || exit 1; \ + echo "$$script completed successfully"; \ + done + @echo "All verification scripts executed successfully." + ## go.updates: Check for updates to go.mod dependencies .PHONY: go.updates go.updates: tools.verify.go-mod-outdated @@ -202,11 +230,11 @@ go.updates: tools.verify.go-mod-outdated ## go.clean: Clean all builds directories and files .PHONY: go.clean go.clean: - @echo "===========> Cleaning all builds TMP_DIR($(TMP_DIR)) AND BIN_DIR($(BIN_DIR)) AND BIN_TOOLS_DIR($(BIN_TOOLS_DIR))" - @-rm -vrf $(TMP_DIR) $(BIN_DIR) $(BIN_TOOLS_DIR) + @echo "===========> Cleaning all builds tmp, bin, logs directories and files" + @-rm -vrf $(TMP_DIR) $(BIN_DIR) $(BIN_TOOLS_DIR) $(LOGS_DIR) @echo "===========> End clean..." -## copyright.help: Show copyright help +## go.help: Show go tools help .PHONY: go.help go.help: scripts/make-rules/golang.mk $(call smallhelp) diff --git a/scripts/make-rules/image.mk b/scripts/make-rules/image.mk index 1b94e92bc..8320bc023 100644 --- a/scripts/make-rules/image.mk +++ b/scripts/make-rules/image.mk @@ -14,7 +14,6 @@ # ============================================================================== # Makefile helper functions for docker image -# TODO: For the time being only used for compilation, it can be arm or amd, please do not delete it, it can be extended with new functions # ============================================================================== # Path: scripts/make-rules/image.mk # docker registry: registry.example.com/namespace/image:tag as: registry.hub.docker.com/cubxxw/: @@ -24,8 +23,11 @@ DOCKER := docker DOCKER_SUPPORTED_API_VERSION ?= 1.32|1.40|1.41 -REGISTRY_PREFIX ?= ghcr.io/OpenIMSDK -IMAGES ?= lvscare +# read: https://github.com/OpenIMSDK/Open-IM-Server/blob/main/docs/conversions/images.md +REGISTRY_PREFIX ?= ghcr.io/openimsdk + +BASE_IMAGE ?= ghcr.io/openim-sigs/openim-bash-image + IMAGE_PLAT ?= $(subst $(SPACE),$(COMMA),$(subst _,/,$(PLATFORMS))) EXTRA_ARGS ?= --no-cache @@ -39,8 +41,8 @@ ifneq ($(EXTRA_ARGS), ) _DOCKER_BUILD_EXTRA_ARGS += $(EXTRA_ARGS) endif -# Determine image files by looking into build/docker/*/Dockerfile -IMAGES_DIR ?= $(wildcard ${ROOT_DIR}/build/docker/*) +# Determine image files by looking into build/images/*/Dockerfile +IMAGES_DIR ?= $(wildcard ${ROOT_DIR}/build/images/*) # Determine images names by stripping out the dir names IMAGES ?= $(filter-out tools,$(foreach image,${IMAGES_DIR},$(notdir ${image}))) @@ -58,11 +60,11 @@ endif # - have enable BuildKit, More info: https://docs.docker.com/develop/develop-images/build_enhancements/ # - be able to push the image for your registry (i.e. if you do not inform a valid value via IMG=> then the export will fail) # To properly provided solutions that supports more than one platform you should use this option. -## Build and push docker image for the manager for cross-platform support +## image.docker-buildx: Build and push docker image for the manager for cross-platform support PLATFORMS ?= linux/arm64,linux/amd64,linux/s390x,linux/ppc64le # copy existing Dockerfile and insert --platform=${BUILDPLATFORM} into Dockerfile.cross, and preserve the original Dockerfile -.PHONY: docker-buildx -docker-buildx: +.PHONY: image.docker-buildx +image.docker-buildx: sed -e '1 s/\(^FROM\)/FROM --platform=\$$\{BUILDPLATFORM\}/; t' -e ' 1,// s//FROM --platform=\$$\{BUILDPLATFORM\}/' Dockerfile > Dockerfile.cross - $(CONTAINER_TOOL) buildx create --name project-v3-builder $(CONTAINER_TOOL) buildx use project-v3-builder @@ -102,25 +104,26 @@ image.build.multiarch: image.verify $(foreach p,$(PLATFORMS),$(addprefix image.b ## image.build.%: Build docker image for a specific platform .PHONY: image.build.% -image.build.%: go.bin.% +image.build.%: go.build.% $(eval IMAGE := $(COMMAND)) $(eval IMAGE_PLAT := $(subst _,/,$(PLATFORM))) $(eval ARCH := $(word 2,$(subst _, ,$(PLATFORM)))) - @echo "===========> Building LOCAL docker image $(IMAGE) $(VERSION) for $(IMAGE_PLAT)" + @echo "===========> Building docker image $(IMAGE) $(VERSION) for $(IMAGE_PLAT)" @mkdir -p $(TMP_DIR)/$(IMAGE)/$(PLATFORM) - @cat $(ROOT_DIR)/docker/$(IMAGE)/Dockerfile\ - >$(TMP_DIR)/$(IMAGE)/Dockerfile - @cp $(BIN_DIR)/$(PLATFORM)/$(IMAGE) $(TMP_DIR)/$(IMAGE)/$(PLATFORM) - - $(eval BUILD_SUFFIX := --load --pull -t $(REGISTRY_PREFIX)/$(IMAGE):$(VERSION) $(TMP_DIR)/$(IMAGE)) - $(eval BUILD_SUFFIX_ARM := --load --pull -t $(REGISTRY_PREFIX)/$(IMAGE).$(ARCH):$(VERSION) $(TMP_DIR)/$(IMAGE)) - @if [ "$(ARCH)" == "amd64" ]; then \ - echo "===========> Creating LOCAL docker image tag $(REGISTRY_PREFIX)/$(IMAGE):$(VERSION) for $(ARCH)"; \ - $(DOCKER) buildx build --platform $(IMAGE_PLAT) $(BUILD_SUFFIX); \ + @awk '/FROM/ {c++; if (c==2) {print; next}} c>=2' $(ROOT_DIR)/build/images/$(IMAGE)/Dockerfile \ +| sed -e "s#BASE_IMAGE#$(BASE_IMAGE)#g" \ + -e 's/--from=builder //g' \ + -e 's#COPY /openim/openim-server/#COPY ./#g' > $(TMP_DIR)/$(IMAGE)/Dockerfile + @cp $(BIN_DIR)/platforms/$(IMAGE_PLAT)/$(IMAGE) $(TMP_DIR)/$(IMAGE) + $(eval BUILD_SUFFIX := $(_DOCKER_BUILD_EXTRA_ARGS) --pull -t $(REGISTRY_PREFIX)/$(IMAGE)-$(ARCH):$(VERSION) $(TMP_DIR)/$(IMAGE)) + @if [ $(shell $(GO) env GOARCH) != $(ARCH) ] ; then \ + $(MAKE) image.daemon.verify ;\ + $(DOCKER) build --platform $(IMAGE_PLAT) $(BUILD_SUFFIX) ; \ else \ - echo "===========> Creating LOCAL docker image tag $(REGISTRY_PREFIX)/$(IMAGE).$(ARCH):$(VERSION) for $(ARCH)"; \ - $(DOCKER) buildx build --platform $(IMAGE_PLAT) $(BUILD_SUFFIX_ARM); \ + $(DOCKER) build $(BUILD_SUFFIX) ; \ fi + @rm -rf $(TMP_DIR)/$(IMAGE) + # https://docs.docker.com/build/building/multi-platform/ # busybox image supports amd64, arm32v5, arm32v6, arm32v7, arm64v8, i386, ppc64le, and s390x @@ -179,7 +182,7 @@ image.manifest.push.multiarch: image.push.multiarch $(addprefix image.manifest.p .PHONY: image.manifest.push.multiarch.% image.manifest.push.multiarch.%: @echo "===========> Pushing manifest $* $(VERSION) to $(REGISTRY_PREFIX) and then remove the local manifest list" - REGISTRY_PREFIX=$(REGISTRY_PREFIX) PLATFROMS="$(PLATFORMS)" IMAGE=$* VERSION=$(VERSION) DOCKER_CLI_EXPERIMENTAL=enabled \ + REGISTRY_PREFIX=$(REGISTRY_PREFIX) PLATFORMS="$(PLATFORMS)" IMAGE=$* VERSION=$(VERSION) DOCKER_CLI_EXPERIMENTAL=enabled \ $(ROOT_DIR)/build/lib/create-manifest.sh ## image.help: Print help for image targets diff --git a/scripts/msg_gateway_start.sh b/scripts/msg_gateway_start.sh deleted file mode 100755 index f5aa00a4e..000000000 --- a/scripts/msg_gateway_start.sh +++ /dev/null @@ -1,82 +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. - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -cd $SCRIPTS_ROOT - -echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}" - -bin_dir="$BIN_DIR" -logs_dir="$OPENIM_ROOT/logs" - -ulimit -n 200000 - -list1=$(cat $config_path | grep openImMessageGatewayPort | awk -F '[:]' '{print $NF}') -list2=$(cat $config_path | grep openImWsPort | awk -F '[:]' '{print $NF}') -list3=$(cat $config_path | grep messageGatewayPrometheusPort | awk -F '[:]' '{print $NF}') -list_to_string $list1 -rpc_ports=($ports_array) -list_to_string $list2 -ws_ports=($ports_array) -list_to_string $list3 -prome_ports=($ports_array) -if [ ${#rpc_ports[@]} -ne ${#ws_ports[@]} ]; then - - echo -e ${RED_PREFIX}"ws_ports does not match push_rpc_ports or prome_ports in quantity!!!"${COLOR_SUFFIX} - exit -1 - -fi -#Check if the service exists -#If it is exists,kill this process -#check=$(ps aux | grep -w ./${openim_msggateway} | grep -v grep | wc -l) -#if [ $check -ge 1 ]; then -# oldPid=$(ps aux | grep -w ./${openim_msggateway} | grep -v grep | awk '{print $2}') -# kill -9 ${oldPid} -#fi -#Waiting port recycling -sleep 1 -cd ${msg_gateway_binary_root} -for ((i = 0; i < ${#ws_ports[@]}; i++)); do - echo "==========================start msg_gateway server===========================">>$OPENIM_ROOT/logs/openIM.log - nohup ./${openim_msggateway} --port ${rpc_ports[$i]} --ws_port ${ws_ports[$i]} --prometheus_port ${prome_ports[$i]} --config_folder_path ${configfile_path} >>$OPENIM_ROOT/logs/openIM.log 2>&1 & -done - -#Check launched service process -sleep 3 -check=$(ps aux | grep -w ./${openim_msggateway} | grep -v grep | wc -l) -allPorts="" -if [ $check -ge 1 ]; then - allNewPid=$(ps aux | grep -w ./${openim_msggateway} | grep -v grep | awk '{print $2}') - for i in $allNewPid; do - ports=$(netstat -netulp | grep -w ${i} | awk '{print $4}' | awk -F '[:]' '{print $NF}') - allPorts=${allPorts}"$ports " - done - echo -e ${SKY_BLUE_PREFIX}"SERVICE START SUCCESS"${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"SERVICE_NAME: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${openim_msggateway}${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allNewPid}${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allPorts}${COLOR_SUFFIX} -else - exit -1 -fi diff --git a/scripts/msg_transfer_start.sh b/scripts/msg_transfer_start.sh deleted file mode 100755 index c0a24104a..000000000 --- a/scripts/msg_transfer_start.sh +++ /dev/null @@ -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. - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}" - -bin_dir="$BIN_DIR" -logs_dir="$OPENIM_ROOT/logs" - -cd $OPENIM_ROOT - -list1=$(cat $config_path | grep messageTransferPrometheusPort | awk -F '[:]' '{print $NF}') -list_to_string $list1 -prome_ports=($ports_array) - -#Check if the service exists -#If it is exists,kill this process -#check=`ps | grep -w ./${openim_msgtransfer} | grep -v grep| wc -l` -#if [ $check -ge 1 ] -#then -#oldPid=`ps | grep -w ./${openim_msgtransfer} | grep -v grep|awk '{print $2}'` -# kill -9 $oldPid -#fi -#Waiting port recycling -sleep 1 - -cd ${msg_transfer_binary_root} -for ((i = 0; i < ${msg_transfer_service_num}; i++)); do - prome_port=${prome_ports[$i]} - cmd="nohup ./${openim_msgtransfer} --config_folder_path ${configfile_path} " - if [ $prome_port != "" ]; then - cmd="$cmd --prometheus_port $prome_port --config_folder_path ${configfile_path} " - fi - echo "==========================start msg_transfer server===========================">>$OPENIM_ROOT/logs/openIM.log - $cmd >>$OPENIM_ROOT/logs/openIM.log 2>&1 & -done - -#Check launched service process -check=`ps -axu| grep -w ./${openim_msgtransfer} | grep -v grep| wc -l` -if [ $check -ge 1 ] -then -newPid=`ps -axu| grep -w ./${openim_msgtransfer} | grep -v grep|awk '{print $2}'` -allPorts="" - echo -e ${SKY_BLUE_PREFIX}"SERVICE START SUCCESS "${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"SERVICE_NAME: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${openim_msgtransfer}${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${newPid}${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allPorts}${COLOR_SUFFIX} -else - exit -1 -fi diff --git a/scripts/path_info.sh b/scripts/path_info.sh deleted file mode 100755 index d7364a7c0..000000000 --- a/scripts/path_info.sh +++ /dev/null @@ -1,141 +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. - -# Determine the architecture and version -architecture=$(uname -m) -version=$(uname -s | tr '[:upper:]' '[:lower:]') - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh - -cd $SCRIPTS_ROOT - -# Define the supported architectures and corresponding bin directories -declare -A supported_architectures=( - ["linux-amd64"]="_output/bin/platforms/linux/amd64" - ["linux-arm64"]="_output/bin/platforms/linux/arm64" - ["linux-mips64"]="_output/bin/platforms/linux/mips64" - ["linux-mips64le"]="_output/bin/platforms/linux/mips64le" - ["linux-ppc64le"]="_output/bin/platforms/linux/ppc64le" - ["linux-s390x"]="_output/bin/platforms/linux/s390x" - ["darwin-amd64"]="_output/bin/platforms/darwin/amd64" - ["windows-amd64"]="_output/bin/platforms/windows/amd64" - ["linux-x86_64"]="_output/bin/platforms/linux/amd64" # Alias for linux-amd64 - ["darwin-x86_64"]="_output/bin/platforms/darwin/amd64" # Alias for darwin-amd64 -) - -declare -A supported_architectures_tools=( - ["linux-amd64"]="_output/bin-tools/platforms/linux/amd64" - ["linux-arm64"]="_output/bin-tools/platforms/linux/arm64" - ["linux-mips64"]="_output/bin-tools/platforms/linux/mips64" - ["linux-mips64le"]="_output/bin-tools/platforms/linux/mips64le" - ["linux-ppc64le"]="_output/bin-tools/platforms/linux/ppc64le" - ["linux-s390x"]="_output/bin-tools/platforms/linux/s390x" - ["darwin-amd64"]="_output/bin-tools/platforms/darwin/amd64" - ["windows-amd64"]="_output/bin-tools/platforms/windows/amd64" - ["linux-x86_64"]="_output/bin-tools/platforms/linux/amd64" # Alias for linux-amd64 - ["darwin-x86_64"]="_output/bin-tools/platforms/darwin/amd64" # Alias for darwin-amd64 -) - -# Check if the architecture and version are supported -if [[ -z ${supported_architectures["$version-$architecture"]} ]]; then - echo -e "${BLUE_PREFIX}================> Unsupported architecture: $architecture or version: $version${COLOR_SUFFIX}" - exit 1 -fi - -echo -e "${BLUE_PREFIX}================> Architecture: $architecture${COLOR_SUFFIX}" - -# Set the BIN_DIR based on the architecture and version -BIN_DIR=${supported_architectures["$version-$architecture"]} -BIN_DIR_TOOLS=${supported_architectures_tools["$version-$architecture"]} - -echo -e "${BLUE_PREFIX}================> BIN_DIR: $OPENIM_ROOT/$BIN_DIR${COLOR_SUFFIX}" - -# Don't put the space between "=" -openim_msggateway="openim-msggateway" -msg_gateway_binary_root="$OPENIM_ROOT/$BIN_DIR" -msg_gateway_source_root="$OPENIM_ROOT/cmd/openim-msggateway/" - -msg_name="openim-rpc-msg" -msg_binary_root="$OPENIM_ROOT/$BIN_DIR" -msg_source_root="$OPENIM_ROOT/cmd/openim-rpc/openim-rpc-msg/" - -push_name="openim-push" -push_binary_root="$OPENIM_ROOT/$BIN_DIR" -push_source_root="$OPENIM_ROOT/cmd/openim-push/" - -openim_msgtransfer="openim-msgtransfer" -msg_transfer_binary_root="$OPENIM_ROOT/$BIN_DIR" -msg_transfer_source_root="$OPENIM_ROOT/cmd/openim-msgtransfer/" -msg_transfer_service_num=4 - -cron_task_name="openim-crontask" -cron_task_binary_root="$OPENIM_ROOT/$BIN_DIR" -cron_task_source_root="$OPENIM_ROOT/cmd/openim-crontask/" - -cmd_utils_name="openim-cmdutils" -cmd_utils_binary_root="$OPENIM_ROOT/$BIN_DIR" -cmd_utils_source_root="$OPENIM_ROOT/cmd/openim-cmdutils/" - -# Global configuration file default dir -config_path="$OPENIM_ROOT/config/config.yaml" -configfile_path="$OPENIM_ROOT/config" -log_path="$OPENIM_ROOT/log" - - -component_check="component" -component_check_binary_root="$OPENIM_ROOT/$BIN_DIR_TOOLS" - -# servicefile dir path -service_source_root=( - # api service file - "$OPENIM_ROOT/cmd/api/" - # rpc service file - "$OPENIM_ROOT/cmd/openim-rpc/openim-rpc-user/" - "$OPENIM_ROOT/cmd/openim-rpc/openim-rpc-friend/" - "$OPENIM_ROOT/cmd/openim-rpc/openim-rpc-group/" - "$OPENIM_ROOT/cmd/openim-rpc/openim-rpc-auth/" - "$OPENIM_ROOT/cmd/openim-rpc/openim-rpc-conversation/" - "$OPENIM_ROOT/cmd/openim-rpc/openim-rpc-third/" - "$OPENIM_ROOT/cmd/openim-crontask" - "${msg_gateway_source_root}" - "${msg_transfer_source_root}" - "${msg_source_root}" - "${push_source_root}" - # "${sdk_server_source_root}" -) - -# service filename -service_names=( - # api service filename - "openim-api" - # rpc service filename - "openim-rpc-user" - "openim-rpc-friend" - "openim-rpc-group" - "openim-rpc-auth" - "openim-rpc-conversation" - "openim-rpc-third" - "openim-crontask" - "${openim_msggateway}" - "${openim_msgtransfer}" - "${msg_name}" - "${push_name}" - # "${sdk_server_name}" -) \ No newline at end of file diff --git a/scripts/push_start.sh b/scripts/push_start.sh deleted file mode 100755 index d3c2f9a8f..000000000 --- a/scripts/push_start.sh +++ /dev/null @@ -1,78 +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. - -# Common utilities, variables and checks for all build scripts. - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -cd $SCRIPTS_ROOT - -echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}" - -bin_dir="$BIN_DIR" -logs_dir="$OPENIM_ROOT/logs" - -cd "$OPENIM_ROOT/scripts/" - -list1=$(cat $config_path | grep openImPushPort | awk -F '[:]' '{print $NF}') -list2=$(cat $config_path | grep pushPrometheusPort | awk -F '[:]' '{print $NF}') -list_to_string $list1 -rpc_ports=($ports_array) -list_to_string $list2 -prome_ports=($ports_array) - -#Check if the service exists -#If it is exists,kill this process -#check=$(ps | grep -w ./${push_name} | grep -v grep | wc -l) -#if [ $check -ge 1 ]; then -# oldPid=$(ps | grep -w ./${push_name} | grep -v grep | awk '{print $2}') -# kill -9 $oldPid -#fi -#Waiting port recycling -sleep 1 -cd ${push_binary_root} - -for ((i = 0; i < ${#rpc_ports[@]}; i++)); do - echo "==========================start push server===========================">>$OPENIM_ROOT/logs/openIM.log - nohup ./${push_name} --port ${rpc_ports[$i]} --prometheus_port ${prome_ports[$i]} >>$OPENIM_ROOT/logs/openIM.log 2>&1 & -done - -sleep 3 -#Check launched service process -check=$(ps -axu| grep -w ./${push_name} | grep -v grep | wc -l) -if [ $check -ge 1 ]; then - newPid=$(ps -axu| grep -w ./${push_name} | grep -v grep | awk '{print $2}') - ports=$(netstat -netulp | grep -w ${newPid} | awk '{print $4}' | awk -F '[:]' '{print $NF}') - allPorts="" - - for i in $ports; do - allPorts=${allPorts}"$i " - done - echo -e ${SKY_BLUE_PREFIX}"SERVICE START SUCCESS "${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"SERVICE_NAME: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${push_name}${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${newPid}${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allPorts}${COLOR_SUFFIX} -else - exit -1 -fi diff --git a/scripts/run-in-gopath.sh b/scripts/run-in-gopath.sh new file mode 100755 index 000000000..9bb8ec882 --- /dev/null +++ b/scripts/run-in-gopath.sh @@ -0,0 +1,34 @@ +#!/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 sets up a temporary openim GOPATH and runs an arbitrary +# command under it. Go tooling requires that the current directory be under +# GOPATH or else it fails to find some things, such as the vendor directory for +# the project. +# Usage: `scripts/run-in-gopath.sh `. + +set -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/scripts/lib/init.sh" + +# This sets up a clean GOPATH and makes sure we are currently in it. +openim::golang::setup_env + +# Run the user-provided command. +"${@}" diff --git a/scripts/start-all.sh b/scripts/start-all.sh new file mode 100755 index 000000000..bdc030211 --- /dev/null +++ b/scripts/start-all.sh @@ -0,0 +1,74 @@ +#!/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 script is the startup script for multiple servers. +#FIXME The full names of the shell scripts that need to be started are placed in the `need_to_start_server_shell` array. + +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/scripts/install/common.sh" + +set +o errexit +openim::golang::check_openim_binaries +if [[ $? -ne 0 ]]; then + openim::log::error "OpenIM binaries are not found. Please run 'make build' to build binaries." + ${OPENIM_ROOT}/scripts/build-all-service.sh +fi +set -o errexit + +echo "You need to start the following scripts in order: ${OPENIM_SERVER_SCRIPTARIES[@]}" +openim::log::install_errexit + +# Function to execute the scripts. +function execute_scripts() { + for script_path in "${OPENIM_SERVER_SCRIPT_START_LIST[@]}"; do + # Extract the script name without extension for argument generation. + script_name_with_prefix=$(basename "$script_path" .sh) + + # Remove the "openim-" prefix. + script_name=${script_name_with_prefix#openim-} + + # Construct the argument based on the script name. + arg="openim::${script_name}::start" + + # Check if the script file exists and is executable. + if [[ -x "$script_path" ]]; then + openim::log::status "Starting script: ${script_path##*/}" # Log the script name. + + # Execute the script with the constructed argument. + "$script_path" "$arg" + + # Check if the script executed successfully. + if [[ $? -eq 0 ]]; then + openim::log::info "${script_path##*/} executed successfully." + else + openim::log::errexit "Error executing ${script_path##*/}." + fi + else + openim::log::errexit "Script ${script_path##*/} is missing or not executable." + fi + sleep 0.5 + done +} + +# TODO Prelaunch tools, simple for now, can abstract functions later +TOOLS_START_SCRIPTS_PATH=${START_SCRIPTS_PATH}/openim-tools.sh +${TOOLS_START_SCRIPTS_PATH} openim::tools::pre-start + +execute_scripts + +${TOOLS_START_SCRIPTS_PATH} openim::tools::post-start \ No newline at end of file diff --git a/scripts/start_all.sh b/scripts/start_all.sh deleted file mode 100755 index 9159dde9c..000000000 --- a/scripts/start_all.sh +++ /dev/null @@ -1,116 +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 script is the startup script for multiple servers. -#FIXME The full names of the shell scripts that need to be started are placed in the `need_to_start_server_shell` array. - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${SCRIPTS_ROOT}")/.. - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -cd $SCRIPTS_ROOT - -echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}" - -if [ ! -d "${OPENIM_ROOT}/_output/bin/platforms" ]; then - # exec build_all_service.sh - "${SCRIPTS_ROOT}/build_all_service.sh" -fi - -bin_dir="$OPENIM_ROOT/_output/bin" -logs_dir="$OPENIM_ROOT/logs" - -if [ ! -d "$bin_dir" ]; then - mkdir -p "$bin_dir" -fi - -if [ ! -d "$logs_dir" ]; then - mkdir -p "$logs_dir" -fi - -if [ ! -d "$sdk_db_dir" ]; then - mkdir -p "$sdk_db_dir" -fi - -# Print title -echo -e "${BOLD_PREFIX}${BLUE_PREFIX}================> OpenIM Server Start${COLOR_SUFFIX}" - -# Get current time -time=$(date +"%Y-%m-%d %H:%M:%S") - -# Print section separator -echo -e "${PURPLE_PREFIX}==========================================================${COLOR_SUFFIX}" - -# Print server start time -echo -e "${BOLD_PREFIX}${CYAN_PREFIX}Server Start Time: ${time}${COLOR_SUFFIX}" - -# Print section separator -echo -e "${PURPLE_PREFIX}==========================================================${COLOR_SUFFIX}" - -cd $SCRIPTS_ROOT - -# FIXME Put the shell script names here -need_to_start_server_shell=( - start_rpc_service.sh - push_start.sh - msg_transfer_start.sh - msg_gateway_start.sh - start_cron.sh -) - -component_check=start_component_check.sh -echo -e "" -chmod +x $component_check -echo -e "=========> ${BACKGROUND_GREEN}Executing ${component_check}...${COLOR_SUFFIX}" -echo -e "" -./$component_check -if [ $? -ne 0 ]; then - # Print error message and exit - echo -e "${RED_PREFIX}${BOLD_PREFIX}Error executing ${component_check}. Exiting...${COLOR_SUFFIX}" - exit -1 -fi - - -# Loop through the script names and execute them -for i in ${need_to_start_server_shell[*]}; do - chmod +x $i - - echo -e "" - # Print script execution message - echo -e "=========> ${BACKGROUND_GREEN}Executing ${i}...${COLOR_SUFFIX}" - echo -e "" - - ./$i - - # Check if the script executed successfully - if [ $? -ne 0 ]; then - # Print error message and exit - echo -e "${RED_PREFIX}${BOLD_PREFIX}Error executing ${i}. Exiting(please check open-im-server/logs/openIM.log)... ${COLOR_SUFFIX}" - exit -1 - fi -done - -# Print section separator -echo -e "${PURPLE_PREFIX}==========================================================${COLOR_SUFFIX}" - -# Print completion message -echo -e "${GREEN_PREFIX}${BOLD_PREFIX}OpenIM Server has been started successfully!${COLOR_SUFFIX}" diff --git a/scripts/start_component_check.sh b/scripts/start_component_check.sh deleted file mode 100644 index 6d9fa227b..000000000 --- a/scripts/start_component_check.sh +++ /dev/null @@ -1,42 +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. - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}" - -bin_dir="$BIN_DIR" -logs_dir="$OPENIM_ROOT/logs" - -cd ${component_check_binary_root} -echo -e "${YELLOW_PREFIX}=======>$PWD${COLOR_SUFFIX}" -cmd="./${component_check}" -echo "==========================start components checking===========================">>$OPENIM_ROOT/logs/openIM.log -$cmd - -if [ $? -ne 0 ]; then - exit 1 -fi - - diff --git a/scripts/start_cron.sh b/scripts/start_cron.sh deleted file mode 100755 index 41b86b4a4..000000000 --- a/scripts/start_cron.sh +++ /dev/null @@ -1,64 +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. - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -cd $SCRIPTS_ROOT - -echo -e "${YELLOW_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" -echo -e "${YELLOW_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}" - -bin_dir="$BIN_DIR" -logs_dir="$OPENIM_ROOT/logs" - -#Check if the service exists -#If it is exists,kill this process -check=`ps | grep -w ./${cron_task_name} | grep -v grep| wc -l` -#if [ $check -ge 1 ] -#then -#oldPid=`ps | grep -w ./${cron_task_name} | grep -v grep|awk '{print $2}'` -# kill -9 $oldPid -#fi -#Waiting port recycling -sleep 1 - -cd ${cron_task_binary_root} -#for ((i = 0; i < ${cron_task_service_num}; i++)); do - echo "==========================start cron_task process===========================">>$OPENIM_ROOT/logs/openIM.log -nohup ./${cron_task_name} >>$OPENIM_ROOT/logs/openIM.log 2>&1 & -#done - -#Check launched service process -check=`ps -axu| grep -w ./${cron_task_name} | grep -v grep| wc -l` -if [ $check -ge 1 ] -then -newPid=`ps -axu| grep -w ./${cron_task_name} | grep -v grep|awk '{print $2}'` -allPorts="" - echo -e ${SKY_BLUE_PREFIX}"SERVICE START SUCCESS "${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"SERVICE_NAME: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${cron_task_name}${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"PID: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${newPid}${COLOR_SUFFIX} - echo -e ${SKY_BLUE_PREFIX}"LISTENING_PORT: "${COLOR_SUFFIX}${BACKGROUND_GREEN}${allPorts}${COLOR_SUFFIX} -else - exit -1 -fi diff --git a/scripts/start_rpc_service.sh b/scripts/start_rpc_service.sh deleted file mode 100755 index a26f6cf87..000000000 --- a/scripts/start_rpc_service.sh +++ /dev/null @@ -1,117 +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. - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -#Include shell font styles and some basic information -source $SCRIPTS_ROOT/style_info.sh -source $SCRIPTS_ROOT/path_info.sh -source $SCRIPTS_ROOT/function.sh - -cd $SCRIPTS_ROOT - -echo -e "${BACKGROUND_GREEN}${CYAN_PREFIX}=======>SCRIPTS_ROOT=$SCRIPTS_ROOT${COLOR_SUFFIX}" -echo -e "${BACKGROUND_GREEN}${CYAN_PREFIX}=======>OPENIM_ROOT=$OPENIM_ROOT${COLOR_SUFFIX}" -echo -e "${BACKGROUND_GREEN}${CYAN_PREFIX}=======>pwd=$PWD${COLOR_SUFFIX}" - -bin_dir="$BIN_DIR" -logs_dir="$OPENIM_ROOT/logs" - -#service filename -service_filename=( - #api - openim-api - #rpc - openim-rpc-user - openim-rpc-friend - openim-rpc-group - openim-rpc-auth - ${msg_name} - openim-rpc-conversation - openim-rpc-third -) - -#service config port name -service_port_name=( - #api port name - openImApiPort - #rpc port name - openImUserPort - openImFriendPort - openImGroupPort - openImAuthPort - openImMessagePort - openImConversationPort - openImThirdPort -) - -service_prometheus_port_name=( - #api port name - openImApiPort - #rpc port name - userPrometheusPort - friendPrometheusPort - groupPrometheusPort - authPrometheusPort - messagePrometheusPort - conversationPrometheusPort - thirdPrometheusPort -) - -for ((i = 0; i < ${#service_filename[*]}; i++)); do - #Check whether the service exists - service_name="ps |grep -w ${service_filename[$i]} |grep -v grep" - count="${service_name}| wc -l" - -# if [ $(eval ${count}) -gt 0 ]; then -# pid="${service_name}| awk '{print \$2}'" -# echo "${service_filename[$i]} service has been started,pid:$(eval $pid)" -# echo "killing the service ${service_filename[$i]} pid:$(eval $pid)" -# #kill the service that existed -# kill -9 $(eval $pid) -# sleep 0.5 -# fi - cd $OPENIM_ROOT - cd $BIN_DIR - # Get the rpc port in the configuration file - portList=$(cat $config_path | grep ${service_port_name[$i]} | awk -F '[:]' '{print $NF}') - list_to_string ${portList} - service_ports=($ports_array) - - portList2=$(cat $config_path | grep ${service_prometheus_port_name[$i]} | awk -F '[:]' '{print $NF}') - list_to_string $portList2 - prome_ports=($ports_array) - #Start related rpc services based on the number of ports - for ((j = 0; j < ${#service_ports[*]}; j++)); do - #Start the service in the background - if [ -z "${prome_ports[$j]}" ]; then - cmd="./${service_filename[$i]} --port ${service_ports[$j]} --config_folder_path ${configfile_path} " - else - cmd="./${service_filename[$i]} --port ${service_ports[$j]} --prometheus_port ${prome_ports[$j]} --config_folder_path ${configfile_path} " - fi - if [ $i -eq 0 -o $i -eq 1 ]; then - cmd="./${service_filename[$i]} --port ${service_ports[$j]}" - fi - echo $cmd - echo "=====================start ${service_filename[$i]}======================">>$OPENIM_ROOT/logs/openIM.log - nohup $cmd >>$OPENIM_ROOT/logs/openIM.log 2>&1 & - sleep 1 - pid="netstat -ntlp|grep $j |awk '{printf \$7}'|cut -d/ -f1" - echo -e "${GREEN_PREFIX}${service_filename[$i]} start success,port number:${service_ports[$j]} pid:$(eval $pid)$COLOR_SUFFIX" - done -done diff --git a/scripts/stop-all.sh b/scripts/stop-all.sh new file mode 100755 index 000000000..611caffe1 --- /dev/null +++ b/scripts/stop-all.sh @@ -0,0 +1,35 @@ +#!/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 stop all openim service +# +# Usage: `scripts/stop.sh`. +# Encapsulated as: `make stop`. + +set -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. + +source "${OPENIM_ROOT}/scripts/install/common.sh" + +echo "++ Ready to stop port: ${OPENIM_SERVER_PORT_LISTARIES[@]}" + +openim::util::stop_services_on_ports ${OPENIM_SERVER_PORT_LISTARIES[@]} + +echo -e "\n++ Stop all processes in the path ${OPENIM_OUTPUT_HOSTBIN}" + +openim::util::stop_services_with_name "${OPENIM_OUTPUT_HOSTBIN}" \ No newline at end of file diff --git a/scripts/stop_all.sh b/scripts/stop_all.sh deleted file mode 100755 index 8bd5aaf34..000000000 --- a/scripts/stop_all.sh +++ /dev/null @@ -1,41 +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. - -#Include shell font styles and some basic information -SCRIPTS_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) -OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. - -#Include shell font styles and some basic information -source $OPENIM_ROOT/scripts/style_info.sh -source $OPENIM_ROOT/scripts/path_info.sh - -bin_dir="$BIN_DIR" -logs_dir="$OPENIM_ROOT/logs" -sdk_db_dir="$OPENIM_ROOT/sdk/db/" - -cd "$SCRIPTS_ROOT" - -for i in ${service_names[*]}; do - #Check whether the service exists - name="ps -aux |grep -w $i |grep -v grep" - count="${name}| wc -l" - if [ $(eval ${count}) -gt 0 ]; then - pid="${name}| awk '{print \$2}'" - echo -e "${SKY_BLUE_PREFIX}Killing service:$i pid:$(eval $pid)${COLOR_SUFFIX}" - #kill the service that existed - kill -9 $(eval $pid) - echo -e "${SKY_BLUE_PREFIX}service:$i was killed ${COLOR_SUFFIX}" - fi -done diff --git a/scripts/style_info.sh b/scripts/style_info.sh deleted file mode 100755 index bc04c84b5..000000000 --- a/scripts/style_info.sh +++ /dev/null @@ -1,67 +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 style-info() { - COLOR_SUFFIX="\033[0m" # End all colors and special effects - - BLACK_PREFIX="\033[30m" # Black prefix - RED_PREFIX="\033[31m" # Red prefix - GREEN_PREFIX="\033[32m" # Green prefix - YELLOW_PREFIX="\033[33m" # Yellow prefix - BLUE_PREFIX="\033[34m" # Blue prefix - PURPLE_PREFIX="\033[35m" # Purple prefix - SKY_BLUE_PREFIX="\033[36m" # Sky blue prefix - WHITE_PREFIX="\033[37m" # White prefix - BOLD_PREFIX="\033[1m" # Bold prefix - UNDERLINE_PREFIX="\033[4m" # Underline prefix - ITALIC_PREFIX="\033[3m" # Italic prefix - - CYAN_PREFIX="033[0;36m" # Cyan prefix - - BACKGROUND_BLACK="\033[40m" # Black background - BACKGROUND_RED="\033[41m" # Red background - BACKGROUND_GREEN="\033[42m" # Green background - BACKGROUND_YELLOW="\033[43m" # Yellow background - BACKGROUND_BLUE="\033[44m" # Blue background - BACKGROUND_PURPLE="\033[45m" # Purple background - BACKGROUND_SKY_BLUE="\033[46m" # Sky blue background - BACKGROUND_WHITE="\033[47m" # White background - - BLINK="\033[5m" # Blinking effect - INVERT="\033[7m" # Invert color - HIDE="\033[8m" # Hide text - - GRAY_PREFIX="\033[90m" # Gray prefix - LIGHT_RED_PREFIX="\033[91m" # Light red prefix - LIGHT_GREEN_PREFIX="\033[92m" # Light green prefix - LIGHT_YELLOW_PREFIX="\033[93m" # Light yellow prefix - LIGHT_BLUE_PREFIX="\033[94m" # Light blue prefix - LIGHT_PURPLE_PREFIX="\033[95m" # Light purple prefix - LIGHT_SKY_BLUE_PREFIX="\033[96m" # Light sky blue prefix - LIGHT_WHITE_PREFIX="\033[97m" # Light white prefix - - BACKGROUND_GRAY="\033[100m" # Gray background - BACKGROUND_LIGHT_RED="\033[101m" # Light red background - BACKGROUND_LIGHT_GREEN="\033[102m" # Light green background - BACKGROUND_LIGHT_YELLOW="\033[103m" # Light yellow background - BACKGROUND_LIGHT_BLUE="\033[104m" # Light blue background - BACKGROUND_LIGHT_PURPLE="\033[105m" # Light purple background - BACKGROUND_LIGHT_SKY_BLUE="\033[106m" # Light sky blue background - BACKGROUND_LIGHT_WHITE="\033[107m" # Light white background - -} - -style-info \ No newline at end of file diff --git a/openim-chat/scripts/LICENSE/LICENSE b/scripts/template/LICENSE similarity index 100% rename from openim-chat/scripts/LICENSE/LICENSE rename to scripts/template/LICENSE diff --git a/openim-chat/scripts/LICENSE/LICENSE_TEMPLATES b/scripts/template/LICENSE_TEMPLATES similarity index 100% rename from openim-chat/scripts/LICENSE/LICENSE_TEMPLATES rename to scripts/template/LICENSE_TEMPLATES diff --git a/scripts/template/boilerplate.txt b/scripts/template/boilerplate.txt new file mode 100644 index 000000000..2f12334fd --- /dev/null +++ b/scripts/template/boilerplate.txt @@ -0,0 +1,3 @@ +Copyright © {{.Year}} {{.Holder}} All rights reserved. +Use of this source code is governed by a MIT style +license that can be found in the LICENSE file. diff --git a/scripts/template/footer.md.tmpl b/scripts/template/footer.md.tmpl new file mode 100644 index 000000000..75a42d23c --- /dev/null +++ b/scripts/template/footer.md.tmpl @@ -0,0 +1,19 @@ +**Full Changelog**: https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/compare/{{ .PreviousTag }}...{{ .Tag }} + +## Get Involved with OpenIM! + +Your patronage towards OpenIM is greatly appreciated 🎉🎉. + +If you encounter any problems during its usage, please create an issue in the [GitHub repository](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/), we're committed to resolving your problem as soon as possible. + +**Here are some ways to get involved with the OpenIM community:** + +📢 **Slack Channel**: Join our Slack channels for discussions, communication, and support. Click [here](https://join.slack.com/t/openimsdk/shared_invite/zt-1tmoj26uf-_FDy3dowVHBiGvLk9e5Xkg) to join the Open-IM-Server Slack team channel. + +📧 **Gmail Contact**: If you have any questions, suggestions, or feedback for our open-source projects, please feel free to [contact us via email](https://mail.google.com/mail/?view=cm&fs=1&tf=1&to=winxu81@gmail.com). + +📖 **Blog**: Stay up-to-date with OpenIM-Server projects and trends by reading our [blog](https://doc.rentsoft.cn/). We share the latest developments, tech trends, and other interesting information related to OpenIM. + +📱 **WeChat**: Add us on WeChat (QR Code) and indicate that you are a user or developer of Open-IM-Server. We'll process your request as soon as possible. + +Remember, your contributions play a vital role in making OpenIM successful, and we look forward to your active participation in our community! 🙌 \ No newline at end of file diff --git a/scripts/template/head.md.tmpl b/scripts/template/head.md.tmpl new file mode 100644 index 000000000..4aba97556 --- /dev/null +++ b/scripts/template/head.md.tmpl @@ -0,0 +1,31 @@ +## Welcome to the {{ .Tag }} release of [OpenIM](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }})!🎉🎉! + +We are excited to release {{.Tag}}, Branch: https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/tree/{{ .Tag }} , Git hash [{{ .ShortCommit }}], Install Address: [{{ .ReleaseURL }}]({{ .ReleaseURL }}) + +Learn more about versions of OpenIM: + ++ We release logs are recorded on [✨CHANGELOG](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/blob/main/CHANGELOG/CHANGELOG.md) + ++ For information on versions of OpenIM and how to maintain branches, read [📚this article](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/blob/main/docs/conversions/version.md) + ++ If you wish to use mirroring, read OpenIM's [🤲image management policy](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/blob/main/docs/conversions/images.md) + +**Want to be one of them 😘?** + +

+ + + + + + + + + +

+ +> **Note** +> @openimbot and @kubbot have made great contributions to the community as community 🤖robots(@openimsdk/bot), respectively. +> Thanks to the @openimsdk/openim team for all their hard work on this release. +> Thank you to all the [💕developers and contributors](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/graphs/contributors), people from all over the world, OpenIM brings us together +> Contributions to this project are welcome! Please see [CONTRIBUTING.md](https://github.com/{{ .Env.USERNAME }}/{{ .ProjectName }}/blob/main/CONTRIBUTING.md) for details. \ No newline at end of file diff --git a/scripts/template/project_README.md b/scripts/template/project_README.md new file mode 100644 index 000000000..96575e681 --- /dev/null +++ b/scripts/template/project_README.md @@ -0,0 +1,41 @@ +# Project myproject + + + +## Features + + + +## Getting Started + +### Prerequisites + + + +### Building + + + +### Running + + + +## Using + + + +## Contributing + + + +## Community(optional) + + + +## Authors + + + +## License + + diff --git a/scripts/update-generated-docs.sh b/scripts/update-generated-docs.sh new file mode 100755 index 000000000..bd2ebb268 --- /dev/null +++ b/scripts/update-generated-docs.sh @@ -0,0 +1,49 @@ +#!/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 file is not intended to be run automatically. It is meant to be run +# immediately before exporting docs. We do not want to check these documents in +# by default. + +set -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/hack/lib/init.sh" + +openim::golang::setup_env + +BINS=( + cmd/gendocs + cmd/genopenimdocs + cmd/genman + cmd/genyaml +) +make -C "${OPENIM_ROOT}" WHAT="${BINS[*]}" + +openim::util::ensure-temp-dir + +openim::util::gen-docs "${OPENIM_TEMP}" + +# remove all of the old docs +openim::util::remove-gen-docs + +# Copy fresh docs into the repo. +# the shopt is so that we get docs/.generated_docs from the glob. +shopt -s dotglob +cp -af "${OPENIM_TEMP}"/* "${OPENIM_ROOT}" +shopt -u dotglob diff --git a/scripts/update-yamlfmt.sh b/scripts/update-yamlfmt.sh new file mode 100755 index 000000000..1e4ad513f --- /dev/null +++ b/scripts/update-yamlfmt.sh @@ -0,0 +1,43 @@ +#!/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 -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/hack/lib/init.sh" + +kube::golang::setup_env + +cd "${OPENIM_ROOT}" + +find_files() { + find . -not \( \ + \( \ + -wholename './output' \ + -o -wholename './.git' \ + -o -wholename './_output' \ + -o -wholename './_gopath' \ + -o -wholename './release' \ + -o -wholename './target' \ + -o -wholename '*/vendor/*' \ + \) -prune \ + \) -name 'OWNERS*' +} + +export GO111MODULE=on +find_files | xargs go run tools/yamlfmt/main.go \ No newline at end of file diff --git a/scripts/verify-pkg-names.sh b/scripts/verify-pkg-names.sh new file mode 100755 index 000000000..1459992e9 --- /dev/null +++ b/scripts/verify-pkg-names.sh @@ -0,0 +1,35 @@ +#!/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 verifies whether codes follow golang convention. +# Usage: `scripts/verify-pkg-names.sh`. + +set -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/scripts/lib/init.sh" + +openim::golang::verify_go_version + +cd "${OPENIM_ROOT}" +if git --no-pager grep -E $'^(import |\t)[a-z]+[A-Z_][a-zA-Z]* "[^"]+"$' -- '**/*.go' ':(exclude)vendor/*' ':(exclude)**/*.pb.go'; then + openim::log::error "Some package aliases break go conventions." + echo "To fix these errors, do not use capitalized or underlined characters" + echo "in pkg aliases. Refer to https://blog.golang.org/package-names for more info." + exit 1 +fi diff --git a/scripts/verify-shellcheck.sh b/scripts/verify-shellcheck.sh new file mode 100755 index 000000000..02445d8d4 --- /dev/null +++ b/scripts/verify-shellcheck.sh @@ -0,0 +1,139 @@ +#!/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 lints each shell script by `shellcheck`. +# Usage: `scripts/verify-shellcheck.sh`. + +set -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/scripts/lib/init.sh" + +# allow overriding docker cli, which should work fine for this script +DOCKER="${DOCKER:-docker}" + +# required version for this script, if not installed on the host we will +# use the official docker image instead. keep this in sync with SHELLCHECK_IMAGE +SHELLCHECK_VERSION="0.8.0" +SHELLCHECK_IMAGE="docker.io/koalaman/shellcheck-alpine:v0.8.0@sha256:f42fde76d2d14a645a848826e54a4d650150e151d9c81057c898da89a82c8a56" + +# disabled lints +disabled=( + # this lint disallows non-constant source, which we use extensively without + # any known bugs + 1090 + # this lint warns when shellcheck cannot find a sourced file + # this wouldn't be a bad idea to warn on, but it fails on lots of path + # dependent sourcing, so just disable enforcing it + 1091 + # this lint prefers command -v to which, they are not the same + 2230 +) +# comma separate for passing to shellcheck +join_by() { + local IFS="$1"; + shift; + echo "$*"; +} +SHELLCHECK_DISABLED="$(join_by , "${disabled[@]}")" +readonly SHELLCHECK_DISABLED + +# ensure we're linting the k8s source tree +cd "${OPENIM_ROOT}" + +# Find all shell scripts excluding: +# - Anything git-ignored - No need to lint untracked files. +# - ./_* - No need to lint output directories. +# - ./.git/* - Ignore anything in the git object store. +# - ./vendor* - Vendored code should be fixed upstream instead. +# - ./third_party/*, but re-include ./third_party/forked/* - only code we +# forked should be linted and fixed. +all_shell_scripts=() +while IFS=$'\n' read -r script; + do git check-ignore -q "$script" || all_shell_scripts+=("$script"); +done < <(find . -name "*.sh" \ + -not \( \ + -path ./_\* -o \ + -path ./.git\* -o \ + -path ./vendor\* -o \ + \( -path ./third_party\* -a -not -path ./third_party/forked\* \) \ + \)) + +# detect if the host machine has the required shellcheck version installed +# if so, we will use that instead. +HAVE_SHELLCHECK=false +if which shellcheck &>/dev/null; then + detected_version="$(shellcheck --version | grep 'version: .*')" + if [[ "${detected_version}" = "version: ${SHELLCHECK_VERSION}" ]]; then + HAVE_SHELLCHECK=true + fi +fi + +# if KUBE_JUNIT_REPORT_DIR is set, disable colorized output. +# Colorized output causes malformed XML in the JUNIT report. +SHELLCHECK_COLORIZED_OUTPUT="auto" +if [[ -n "${KUBE_JUNIT_REPORT_DIR:-}" ]]; then + SHELLCHECK_COLORIZED_OUTPUT="never" +fi + +# common arguments we'll pass to shellcheck +SHELLCHECK_OPTIONS=( + # allow following sourced files that are not specified in the command, + # we need this because we specify one file at a time in order to trivially + # detect which files are failing + "--external-sources" + # include our disabled lints + "--exclude=${SHELLCHECK_DISABLED}" + # set colorized output + "--color=${SHELLCHECK_COLORIZED_OUTPUT}" +) + +# tell the user which we've selected and lint all scripts +# The shellcheck errors are printed to stdout by default, hence they need to be redirected +# to stderr in order to be well parsed for Junit representation by juLog function +res=0 +if ${HAVE_SHELLCHECK}; then + openim::log::info "Using host shellcheck ${SHELLCHECK_VERSION} binary." + shellcheck "${SHELLCHECK_OPTIONS[@]}" "${all_shell_scripts[@]}" >&2 || res=$? +else + openim::log::info "Using shellcheck ${SHELLCHECK_VERSION} docker image." + "${DOCKER}" run \ + --rm -v "${OPENIM_ROOT}:${OPENIM_ROOT}" -w "${OPENIM_ROOT}" \ + "${SHELLCHECK_IMAGE}" \ + shellcheck "${SHELLCHECK_OPTIONS[@]}" "${all_shell_scripts[@]}" >&2 || res=$? +fi + +# print a message based on the result +if [ $res -eq 0 ]; then + echo 'Congratulations! All shell files are passing lint :-)' +else + { + echo + echo 'Please review the above warnings. You can test via "./scripts/verify-shellcheck.sh"' + echo 'If the above warnings do not make sense, you can exempt this warning with a comment' + echo ' (if your reviewer is okay with it).' + echo 'In general please prefer to fix the error, we have already disabled specific lints' + echo ' that the project chooses to ignore.' + echo 'See: https://github.com/koalaman/shellcheck/wiki/Ignore#ignoring-one-specific-instance-in-a-file' + echo + } >&2 + exit 1 +fi + +# preserve the result +exit $res diff --git a/scripts/verify-spelling.sh b/scripts/verify-spelling.sh new file mode 100755 index 000000000..487c68cde --- /dev/null +++ b/scripts/verify-spelling.sh @@ -0,0 +1,41 @@ +#!/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 checks commonly misspelled English words in all files in the +# working directory by client9/misspell package. +# Usage: `scripts/verify-spelling.sh`. + +set -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +export OPENIM_ROOT +source "${OPENIM_ROOT}/scripts/lib/init.sh" + +# Ensure that we find the binaries we build before anything else. +export GOBIN="${KUBE_OUTPUT_BINPATH}" +PATH="${GOBIN}:${PATH}" + +# Install tools we need +pushd "${OPENIM_ROOT}/tools" >/dev/null + GO111MODULE=on go install github.com/client9/misspell/cmd/misspell +popd >/dev/null + +# Spell checking +# All the skipping files are defined in scripts/.spelling_failures +skipping_file="${OPENIM_ROOT}/scripts/.spelling_failures" +failing_packages=$(sed "s| | -e |g" "${skipping_file}") +git ls-files | grep -v -e "${failing_packages}" | xargs misspell -i "Creater,creater,ect" -error -o stderr diff --git a/scripts/verify-typecheck.sh b/scripts/verify-typecheck.sh new file mode 100755 index 000000000..0aa79482a --- /dev/null +++ b/scripts/verify-typecheck.sh @@ -0,0 +1,41 @@ +#!/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 does a fast type check of script srnetes code for all platforms. +# Usage: `scripts/verify-typecheck.sh`. + +set -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/scripts/lib/init.sh" + +openim::golang::verify_go_version + +cd "${OPENIM_ROOT}" + +# As of June, 2020 the typecheck tool is written in terms of go/packages, but +# that library doesn't work well with multiple modules. Until that is done, +# force this tooling to run in a fake GOPATH. +ret=0 +TYPECHECK_SERIAL="${TYPECHECK_SERIAL:-false}" +scripts/run-in-gopath.sh \ + go run test/typecheck/typecheck.go "$@" "--serial=$TYPECHECK_SERIAL" || ret=$? +if [[ $ret -ne 0 ]]; then + openim::log::error "Type Check has failed. This may cause cross platform build failures." >&2 + openim::log::error "Please see https://github.com/OpenIMSDK/Open-IM-Server/tree/main/test/typecheck for more information." >&2 + exit 1 +fi diff --git a/scripts/verify-yamlfmt.sh b/scripts/verify-yamlfmt.sh new file mode 100755 index 000000000..82e1c528d --- /dev/null +++ b/scripts/verify-yamlfmt.sh @@ -0,0 +1,48 @@ +#!/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 checks whether the OWNERS files need to be formatted or not by +# `yamlfmt`. Run `scripts/update-yamlfmt.sh` to actually format sources. +# +# Usage: `scripts/verify-yamlfmt.sh`. + +set -o errexit +set -o nounset +set -o pipefail + +OPENIM_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. +source "${OPENIM_ROOT}/scripts/lib/init.sh" + +openim::util::ensure_clean_working_dir +# This sets up the environment, like GOCACHE, which keeps the worktree cleaner. +openim::golang::setup_env + +_tmpdir="$(openim::realpath "$(mktemp -d -t "$(basename "$0").XXXXXX")")" +git worktree add -f -q "${_tmpdir}" HEAD +openim::util::trap_add "git worktree remove -f ${_tmpdir}" EXIT +cd "${_tmpdir}" + +# Format YAML files +hack/update-yamlfmt.sh + +# Test for diffs +diffs=$(git status --porcelain | wc -l) +if [[ ${diffs} -gt 0 ]]; then + echo "YAML files need to be formatted" >&2 + git diff + echo "Please run 'hack/update-yamlfmt.sh'" >&2 + exit 1 +fi \ No newline at end of file diff --git a/scripts/wait-for-it.sh b/scripts/wait-for-it.sh index 32c1cbb0b..5a1022d26 100755 --- a/scripts/wait-for-it.sh +++ b/scripts/wait-for-it.sh @@ -1,17 +1,21 @@ #!/usr/bin/env bash - -# Copyright 2020 Lingfei Kong . All rights reserved. -# Use of this source code is governed by a MIT style -# license that can be found in the LICENSE file. - -# Use this script to test if a given TCP host/port are available +# 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. WAITFORIT_cmdname=${0##*/} -openim_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" -source "${openim_root}/scripts/lib/color.sh" - -echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then info "$@" 1>&2; fi } +echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi } usage() { @@ -30,7 +34,7 @@ USAGE exit 1 } -function wait_for() +wait_for() { if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT" @@ -44,7 +48,7 @@ function wait_for() nc -z $WAITFORIT_HOST $WAITFORIT_PORT WAITFORIT_result=$? else - (echo > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1 + (echo -n > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1 WAITFORIT_result=$? fi if [[ $WAITFORIT_result -eq 0 ]]; then @@ -57,7 +61,7 @@ function wait_for() return $WAITFORIT_result } -function wait_for_wrapper() +wait_for_wrapper() { # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692 if [[ $WAITFORIT_QUIET -eq 1 ]]; then @@ -133,7 +137,7 @@ do usage ;; *) - warn "Unknown argument: $1" + echoerr "Unknown argument: $1" usage ;; esac @@ -149,16 +153,20 @@ WAITFORIT_STRICT=${WAITFORIT_STRICT:-0} WAITFORIT_CHILD=${WAITFORIT_CHILD:-0} WAITFORIT_QUIET=${WAITFORIT_QUIET:-0} -# check to see if timeout is from busybox? +# Check to see if timeout is from busybox? WAITFORIT_TIMEOUT_PATH=$(type -p timeout) WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH) -if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then - WAITFORIT_ISBUSY=1 - WAITFORIT_BUSYTIMEFLAG="-t" +WAITFORIT_BUSYTIMEFLAG="" +if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then + WAITFORIT_ISBUSY=1 + # Check if busybox timeout uses -t flag + # (recent Alpine versions don't support -t anymore) + if timeout &>/dev/stdout | grep -q -e '-t '; then + WAITFORIT_BUSYTIMEFLAG="-t" + fi else - WAITFORIT_ISBUSY=0 - WAITFORIT_BUSYTIMEFLAG="" + WAITFORIT_ISBUSY=0 fi if [[ $WAITFORIT_CHILD -gt 0 ]]; then diff --git a/test/README.md b/test/README.md new file mode 100644 index 000000000..16f75d5a4 --- /dev/null +++ b/test/README.md @@ -0,0 +1,15 @@ +## Run the Tests + +To run a single test or set of tests, you'll need the [Ginkgo](https://github.com/onsi/ginkgo) tool installed on your +machine: + +```console +go install github.com/onsi/ginkgo/ginkgo@latest +``` + +```shell +ginkgo --help + --focus value + If set, ginkgo will only run specs that match this regular expression. Can be specified multiple times, values are ORed. + +``` diff --git a/test/jwt/main.go b/test/jwt/main.go new file mode 100644 index 000000000..3676a3793 --- /dev/null +++ b/test/jwt/main.go @@ -0,0 +1,48 @@ +// 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 main + +import ( + "fmt" + + "github.com/golang-jwt/jwt/v4" +) + +func main() { + rawJWT := `eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJpYW0uYXV0aHoubWFybW90ZWR1LmNvbSIsImV4cCI6MTYwNDEyODQwMywiaWF0IjoxNjA0MTI4NDAyLCJpc3MiOiJpYW1jdGwiLCJraWQiOiJpZDEifQ.Itr5u4C-nTeA01qbjjl7RzuPD-aSQazsJZY_Z25aGnI` + + // Verify the token + claims := &jwt.MapClaims{} + parsedT, err := jwt.ParseWithClaims(rawJWT, claims, func(token *jwt.Token) (interface{}, error) { + // Validate the alg is HMAC signature + if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { + return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"]) + } + + if kid, ok := token.Header["kid"].(string); ok { + fmt.Println("kid", kid) + } + + return []byte("key1"), nil + }) + + if err != nil || !parsedT.Valid { + fmt.Println("token valid failed", err) + + return + } + + fmt.Println("ok") +} diff --git a/test/testdata/README.md b/test/testdata/README.md new file mode 100644 index 000000000..74cdb71f8 --- /dev/null +++ b/test/testdata/README.md @@ -0,0 +1,64 @@ + +# Test Data for OpenIM Server + +This directory (`testdata`) contains various JSON formatted data files that are used for testing the OpenIM Server. + +## Structure + +```bash +testdata/ +│ +├── README.md # 描述该目录下各子目录和文件的作用 +│ +├── db/ # 存储模拟的数据库数据 +│ ├── users.json # 用户的模拟数据 +│ └── messages.json # 消息的模拟数据 +│ +├── requests/ # 存储模拟的请求数据 +│ ├── login.json # 模拟登陆请求 +│ ├── register.json # 模拟注册请求 +│ └── sendMessage.json # 模拟发送消息请求 +│ +└── responses/ # 存储模拟的响应数据 + ├── login.json # 模拟登陆响应 + ├── register.json # 模拟注册响应 + └── sendMessage.json # 模拟发送消息响应 +``` + +Here is an overview of what each subdirectory or file represents: + +- `db/` - This directory contains mock data mimicking the actual database contents. + - `users.json` - Represents a list of users in the system. Each entry contains user-specific information such as user ID, username, password hash, etc. + - `messages.json` - Contains a list of messages exchanged between users. Each message entry includes the sender's and receiver's user IDs, message content, timestamp, etc. +- `requests/` - This directory contains mock requests that a client might send to the server. + - `login.json` - Represents a user login request. It includes fields such as username and password. + - `register.json` - Mimics a user registration request. Contains details such as username, password, email, etc. + - `sendMessage.json` - Simulates a message sending request from a user to another user. +- `responses/` - This directory holds the expected server responses for the respective requests. + - `login.json` - Represents a successful login response from the server. It typically includes a session token and user-specific information. + - `register.json` - Simulates a successful registration response from the server, usually containing the new user's ID, username, etc. + - `sendMessage.json` - Depicts a successful message sending response from the server, confirming the delivery of the message. + +## JSON Format + +All the data files in this directory are in JSON format. JSON (JavaScript Object Notation) is a lightweight data-interchange format that is easy for humans to read and write and easy for machines to parse and generate. + +Here is a simple example of what a JSON file might look like: + +```bash + "users": [ + { + "id": 1, + "username": "user1", + "password": "password1" + }, + { + "id": 2, + "username": "user2", + "password": "password2" + } + ] + +``` + +In this example, "users" is an array of user objects. Each user object has an "id", "username", and "password". diff --git a/test/testdata/db/messages.json b/test/testdata/db/messages.json new file mode 100644 index 000000000..e69de29bb diff --git a/test/testdata/db/users.json b/test/testdata/db/users.json new file mode 100644 index 000000000..e69de29bb diff --git a/test/testdata/requests/login.json b/test/testdata/requests/login.json new file mode 100644 index 000000000..e69de29bb diff --git a/test/testdata/requests/register.json b/test/testdata/requests/register.json new file mode 100644 index 000000000..e69de29bb diff --git a/test/testdata/requests/sendMessage.json b/test/testdata/requests/sendMessage.json new file mode 100644 index 000000000..e69de29bb diff --git a/test/testdata/responses/login.json b/test/testdata/responses/login.json new file mode 100644 index 000000000..e69de29bb diff --git a/test/testdata/responses/register.json b/test/testdata/responses/register.json new file mode 100644 index 000000000..e69de29bb diff --git a/test/testdata/responses/sendMessage.json b/test/testdata/responses/sendMessage.json new file mode 100644 index 000000000..e69de29bb diff --git a/test/typecheck/README.md b/test/typecheck/README.md new file mode 100644 index 000000000..6ba462ec9 --- /dev/null +++ b/test/typecheck/README.md @@ -0,0 +1,27 @@ +# OpenIM Typecheck + +OpenIM Typecheck 为所有 Go 构建平台进行跨平台源代码类型检查。 + +## 优点 + +- **速度**:OpenIM 完整编译大约需要 3 分钟,而使用 Typecheck 只需数秒。 +- **资源消耗**:与需要 >40GB 的 RAM 不同,Typecheck 只需 <8GB 的 RAM。 + +## 实现 + +OpenIM Typecheck 使用 Go 内置的解析和类型检查库 (`go/parser` 和 `go/types`)。然而,这些库并不是 go 编译器所使用的。偶尔会出现不匹配的情况,但总的来说,它们是相当接近的。 + +## 错误处理 + +如果错误不会阻止构建,可以忽略。 + +**`go/types` 报告的错误,但 `go build` 不会**: +- **真正的错误**(根据规范): + - 应尽量修复。如果无法修复或正在进行中(例如,已被外部引用的代码),则可以忽略。 + - 例如:闭包中的未使用变量 +- **不真实的错误**: + - 应忽略并在适当的情况下向上游报告。 + - 例如:staging 和 generated 类型之间的类型检查不匹配 + +**`go build` 报告的错误,但我们不会**: +- CGo 错误,包括语法和链接器错误。 diff --git a/test/typecheck/go.mod b/test/typecheck/go.mod new file mode 100644 index 000000000..5bc1000ed --- /dev/null +++ b/test/typecheck/go.mod @@ -0,0 +1,10 @@ +module github.com/OpenIMSDK/Open-IM-Server/test/typecheck + +go 1.20 + +require golang.org/x/tools v0.12.0 + +require ( + golang.org/x/mod v0.12.0 // indirect + golang.org/x/sys v0.11.0 // indirect +) diff --git a/test/typecheck/go.sum b/test/typecheck/go.sum new file mode 100644 index 000000000..14a66101b --- /dev/null +++ b/test/typecheck/go.sum @@ -0,0 +1,7 @@ +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= diff --git a/test/typecheck/typecheck.go b/test/typecheck/typecheck.go new file mode 100644 index 000000000..30bce3caa --- /dev/null +++ b/test/typecheck/typecheck.go @@ -0,0 +1,320 @@ +// 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. + +// do a fast type check of kubernetes code, for all platforms. +package main + +import ( + "flag" + "fmt" + "io" + "log" + "os" + "path/filepath" + "sort" + "strings" + "sync" + "time" + + "golang.org/x/tools/go/packages" +) + +var ( + verbose = flag.Bool("verbose", false, "print more information") + cross = flag.Bool("cross", true, "build for all platforms") + platforms = flag.String("platform", "", "comma-separated list of platforms to typecheck") + timings = flag.Bool("time", false, "output times taken for each phase") + defuses = flag.Bool("defuse", false, "output defs/uses") + serial = flag.Bool("serial", false, "don't type check platforms in parallel (equivalent to --parallel=1)") + parallel = flag.Int("parallel", 2, "limits how many platforms can be checked in parallel. 0 means no limit.") + skipTest = flag.Bool("skip-test", false, "don't type check test code") + tags = flag.String("tags", "", "comma-separated list of build tags to apply in addition to go's defaults") + ignoreDirs = flag.String("ignore-dirs", "", "comma-separated list of directories to ignore in addition to the default hardcoded list including staging, vendor, and hidden dirs") + + // When processed in order, windows and darwin are early to make + // interesting OS-based errors happen earlier. + crossPlatforms = []string{ + "linux/amd64", "windows/386", + "darwin/amd64", "darwin/arm64", + "linux/arm", "linux/386", + "windows/amd64", "linux/arm64", + "linux/ppc64le", "linux/s390x", + "windows/arm64", + } + + // directories we always ignore + standardIgnoreDirs = []string{ + // Staging code is symlinked from vendor/k8s.io, and uses import + // paths as if it were inside of vendor/. It fails typechecking + // inside of staging/, but works when typechecked as part of vendor/. + "staging", + // OS-specific vendor code tends to be imported by OS-specific + // packages. We recursively typecheck imported vendored packages for + // each OS, but don't typecheck everything for every OS. + "vendor", + "_output", + // This is a weird one. /testdata/ is *mostly* ignored by Go, + // and this translates to kubernetes/vendor not working. + // edit/record.go doesn't compile without gopkg.in/yaml.v2 + // in $GOSRC/$GOROOT (both typecheck and the shell script). + "pkg/kubectl/cmd/testdata/edit", + // Tools we use for maintaining the code base but not necessarily + // ship as part of the release + "hack/tools", + } +) + +func newConfig(platform string) *packages.Config { + platSplit := strings.Split(platform, "/") + goos, goarch := platSplit[0], platSplit[1] + mode := packages.NeedName | packages.NeedFiles | packages.NeedTypes | packages.NeedSyntax | packages.NeedDeps | packages.NeedImports | packages.NeedModule + if *defuses { + mode = mode | packages.NeedTypesInfo + } + env := append(os.Environ(), + "CGO_ENABLED=1", + fmt.Sprintf("GOOS=%s", goos), + fmt.Sprintf("GOARCH=%s", goarch)) + tagstr := "selinux" + if *tags != "" { + tagstr = tagstr + "," + *tags + } + flags := []string{"-tags", tagstr} + + return &packages.Config{ + Mode: mode, + Env: env, + BuildFlags: flags, + Tests: !(*skipTest), + } +} + +type collector struct { + dirs []string + ignoreDirs []string +} + +func newCollector(ignoreDirs string) collector { + c := collector{ + ignoreDirs: append([]string(nil), standardIgnoreDirs...), + } + if ignoreDirs != "" { + c.ignoreDirs = append(c.ignoreDirs, strings.Split(ignoreDirs, ",")...) + } + return c +} + +func (c *collector) walk(roots []string) error { + for _, root := range roots { + err := filepath.Walk(root, c.handlePath) + if err != nil { + return err + } + } + sort.Strings(c.dirs) + return nil +} + +// handlePath walks the filesystem recursively, collecting directories, +// ignoring some unneeded directories (hidden/vendored) that are handled +// specially later. +func (c *collector) handlePath(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + name := info.Name() + // Ignore hidden directories (.git, .cache, etc) + if (len(name) > 1 && (name[0] == '.' || name[0] == '_')) || name == "testdata" { + if *verbose { + fmt.Printf("DBG: skipping dir %s\n", path) + } + return filepath.SkipDir + } + for _, dir := range c.ignoreDirs { + if path == dir { + if *verbose { + fmt.Printf("DBG: ignoring dir %s\n", path) + } + return filepath.SkipDir + } + } + // Make dirs into relative pkg names. + // NOTE: can't use filepath.Join because it elides the leading "./" + pkg := path + if !strings.HasPrefix(pkg, "./") { + pkg = "./" + pkg + } + c.dirs = append(c.dirs, pkg) + if *verbose { + fmt.Printf("DBG: added dir %s\n", path) + } + } + return nil +} + +func (c *collector) verify(plat string) ([]string, error) { + errors := []packages.Error{} + start := time.Now() + config := newConfig(plat) + + rootPkgs, err := packages.Load(config, c.dirs...) + if err != nil { + return nil, err + } + + // Recursively import all deps and flatten to one list. + allMap := map[string]*packages.Package{} + for _, pkg := range rootPkgs { + if *verbose { + serialFprintf(os.Stdout, "pkg %q has %d GoFiles\n", pkg.PkgPath, len(pkg.GoFiles)) + } + allMap[pkg.PkgPath] = pkg + if len(pkg.Imports) > 0 { + for _, imp := range pkg.Imports { + if *verbose { + serialFprintf(os.Stdout, "pkg %q imports %q\n", pkg.PkgPath, imp.PkgPath) + } + allMap[imp.PkgPath] = imp + } + } + } + keys := make([]string, 0, len(allMap)) + for k := range allMap { + keys = append(keys, k) + } + sort.Strings(keys) + allList := make([]*packages.Package, 0, len(keys)) + for _, k := range keys { + allList = append(allList, allMap[k]) + } + + for _, pkg := range allList { + if len(pkg.GoFiles) > 0 { + if len(pkg.Errors) > 0 && (pkg.PkgPath == "main" || strings.Contains(pkg.PkgPath, ".")) { + errors = append(errors, pkg.Errors...) + } + } + if *defuses { + for id, obj := range pkg.TypesInfo.Defs { + serialFprintf(os.Stdout, "%s: %q defines %v\n", + pkg.Fset.Position(id.Pos()), id.Name, obj) + } + for id, obj := range pkg.TypesInfo.Uses { + serialFprintf(os.Stdout, "%s: %q uses %v\n", + pkg.Fset.Position(id.Pos()), id.Name, obj) + } + } + } + if *timings { + serialFprintf(os.Stdout, "%s took %.1fs\n", plat, time.Since(start).Seconds()) + } + return dedup(errors), nil +} + +func dedup(errors []packages.Error) []string { + ret := []string{} + + m := map[string]bool{} + for _, e := range errors { + es := e.Error() + if !m[es] { + ret = append(ret, es) + m[es] = true + } + } + return ret +} + +var outMu sync.Mutex + +func serialFprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + outMu.Lock() + defer outMu.Unlock() + return fmt.Fprintf(w, format, a...) +} + +func main() { + flag.Parse() + args := flag.Args() + + if *verbose { + *serial = true // to avoid confusing interleaved logs + } + + if len(args) == 0 { + args = append(args, ".") + } + + c := newCollector(*ignoreDirs) + + if err := c.walk(args); err != nil { + log.Fatalf("Error walking: %v", err) + } + + plats := crossPlatforms[:] + if *platforms != "" { + plats = strings.Split(*platforms, ",") + } else if !*cross { + plats = plats[:1] + } + + var wg sync.WaitGroup + var failMu sync.Mutex + failed := false + + if *serial { + *parallel = 1 + } else if *parallel == 0 { + *parallel = len(plats) + } + throttle := make(chan int, *parallel) + + for _, plat := range plats { + wg.Add(1) + go func(plat string) { + // block until there's room for this task + throttle <- 1 + defer func() { + // indicate this task is done + <-throttle + }() + + f := false + serialFprintf(os.Stdout, "type-checking %s\n", plat) + errors, err := c.verify(plat) + if err != nil { + serialFprintf(os.Stderr, "ERROR(%s): failed to verify: %v\n", plat, err) + f = true + } else if len(errors) > 0 { + for _, e := range errors { + // Special case CGo errors which may depend on headers we + // don't have. + if !strings.HasSuffix(e, "could not import C (no metadata for C)") { + f = true + serialFprintf(os.Stderr, "ERROR(%s): %s\n", plat, e) + } + } + } + failMu.Lock() + failed = failed || f + failMu.Unlock() + wg.Done() + }(plat) + } + wg.Wait() + if failed { + os.Exit(1) + } +} \ No newline at end of file diff --git a/test/typecheck/typecheck_test.go b/test/typecheck/typecheck_test.go new file mode 100644 index 000000000..0b6c1ce0c --- /dev/null +++ b/test/typecheck/typecheck_test.go @@ -0,0 +1,121 @@ +// 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 main + +import ( + "errors" + "flag" + "os" + "path/filepath" + "testing" + + "golang.org/x/tools/go/packages" +) + +// This exists because `go` is not always in the PATH when running CI. +var goBinary = flag.String("go", "", "path to a `go` binary") + +func TestVerify(t *testing.T) { + // x/tools/packages is going to literally exec `go`, so it needs some + // setup. + setEnvVars(t) + + tcs := []struct { + path string + expect int + }{ + {"./testdata/good", 0}, + {"./testdata/bad", 18}, + } + + for _, tc := range tcs { + c := newCollector("") + if err := c.walk([]string{tc.path}); err != nil { + t.Fatalf("error walking %s: %v", tc.path, err) + } + + errs, err := c.verify("linux/amd64") + if err != nil { + t.Errorf("unexpected error: %v", err) + } else if len(errs) != tc.expect { + t.Errorf("Expected %d errors, got %d: %v", tc.expect, len(errs), errs) + } + } +} + +func setEnvVars(t testing.TB) { + t.Helper() + if *goBinary != "" { + newPath := filepath.Dir(*goBinary) + curPath := os.Getenv("PATH") + if curPath != "" { + newPath = newPath + ":" + curPath + } + t.Setenv("PATH", newPath) + } + if os.Getenv("HOME") == "" { + t.Setenv("HOME", "/tmp") + } +} + +func TestHandlePath(t *testing.T) { + c := collector{ + ignoreDirs: standardIgnoreDirs, + } + e := errors.New("ex") + i, _ := os.Stat(".") // i.IsDir() == true + if c.handlePath("foo", nil, e) != e { + t.Error("handlePath not returning errors") + } + if c.handlePath("vendor", i, nil) != filepath.SkipDir { + t.Error("should skip vendor") + } +} + +func TestDedup(t *testing.T) { + testcases := []struct { + input []packages.Error + expected int + }{{ + input: nil, + expected: 0, + }, { + input: []packages.Error{ + {Pos: "file:7", Msg: "message", Kind: packages.ParseError}, + }, + expected: 1, + }, { + input: []packages.Error{ + {Pos: "file:7", Msg: "message1", Kind: packages.ParseError}, + {Pos: "file:8", Msg: "message2", Kind: packages.ParseError}, + }, + expected: 2, + }, { + input: []packages.Error{ + {Pos: "file:7", Msg: "message1", Kind: packages.ParseError}, + {Pos: "file:8", Msg: "message2", Kind: packages.ParseError}, + {Pos: "file:7", Msg: "message1", Kind: packages.ParseError}, + }, + expected: 2, + }} + + for i, tc := range testcases { + out := dedup(tc.input) + if len(out) != tc.expected { + t.Errorf("[%d] dedup(%v) = '%v', expected %d", + i, tc.input, out, tc.expected) + } + } +} \ No newline at end of file diff --git a/test/wrktest.sh b/test/wrktest.sh index f57d16402..61b159b80 100755 --- a/test/wrktest.sh +++ b/test/wrktest.sh @@ -1,25 +1,30 @@ -#!/bin/bash - -# Copyright 2020 Lingfei Kong . All rights reserved. -# Use of this source code is governed by a MIT style -# license that can be found in the LICENSE file. +#!/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. : << EOF The API performance test script automatically executes wrk commands, collects data, analyzes it, and calls gnuplot to plot it Usage (to test API performance) : - -Start the openim-api(port 10002) - -Execute the test script: ./wrktest.sh +1. Start the openim-api(port 10002) +2. Execute the test script: ./wrktest.sh The script will generate the data file.dat, each column meaning: concurrency QPS average response time success rate Usage (Compare the results of 2 tests) - 1. The performance test:. / wrktest. Sh openim apiserver - http://127.0.0.1:10002/healthz - -Execute the command:./wrktest.sh diff apiserver.dat http.dat +2. Execute the command:./wrktest.sh diff apiserver.dat http.dat > Note: Make sure you have wrk and gnuplot installed on your system diff --git a/tools/README.md b/tools/README.md index 13339766d..45c66564d 100644 --- a/tools/README.md +++ b/tools/README.md @@ -12,26 +12,6 @@ As openim is using go1.18's [workspace feature](https://go.dev/doc/tutorial/work You can execute the following commands to do things above: ```bash -# 4dd91a700d3f:/openim# tree -# . -# ├── LICENSE -# ├── README.md -# ├── openim-chat -# │ ├── bin -# │ ├── config -# │ ├── logs -# │ └── scripts -# ├── openim-server -# │ ├── bin -# │ ├── config -# │ ├── logs -# │ └── scripts -# ├── openkf -# │ ├── bin -# │ ├── config -# │ ├── logs -# │ └── scripts -# cd tools_code_dir # edit the CRD_NAME and CRD_GROUP to your own export OPENIM_TOOLS_NAME= diff --git a/tools/changelog/changelog.go b/tools/changelog/changelog.go new file mode 100644 index 000000000..7428db5fa --- /dev/null +++ b/tools/changelog/changelog.go @@ -0,0 +1,308 @@ +// 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 main + +import ( + "fmt" + "log" + "os" + "os/exec" + "regexp" + "sort" + "strings" +) + +var ( + mergeRequest = regexp.MustCompile(`Merge pull request #([\d]+)`) + webconsoleBump = regexp.MustCompile(regexp.QuoteMeta("bump(github.com/openshift/origin-web-console): ") + `([\w]+)`) + upstreamKube = regexp.MustCompile(`^UPSTREAM: (\d+)+:(.+)`) + upstreamRepo = regexp.MustCompile(`^UPSTREAM: ([\w/-]+): (\d+)+:(.+)`) + prefix = regexp.MustCompile(`^[\w-]: `) + + assignments = []prefixAssignment{ + {"cluster up", "cluster"}, + {" pv ", "storage"}, + {"haproxy", "router"}, + {"router", "router"}, + {"route", "route"}, + {"authoriz", "auth"}, + {"rbac", "auth"}, + {"authent", "auth"}, + {"reconcil", "auth"}, + {"auth", "auth"}, + {"role", "auth"}, + {" dc ", "deploy"}, + {"deployment", "deploy"}, + {"rolling", "deploy"}, + {"security context constr", "security"}, + {"scc", "security"}, + {"pipeline", "build"}, + {"build", "build"}, + {"registry", "registry"}, + {"registries", "image"}, + {"image", "image"}, + {" arp ", "network"}, + {" cni ", "network"}, + {"egress", "network"}, + {"network", "network"}, + {"oc ", "cli"}, + {"template", "template"}, + {"etcd", "server"}, + {"pod", "node"}, + {"hack/", "hack"}, + {"e2e", "test"}, + {"integration", "test"}, + {"cluster", "cluster"}, + {"master", "server"}, + {"packages", "hack"}, + {"api", "server"}, + } +) + +type prefixAssignment struct { + term string + prefix string +} + +type commit struct { + short string + parents []string + message string +} + +func contains(arr []string, value string) bool { + for _, s := range arr { + if s == value { + return true + } + } + return false +} + +func main() { + log.SetFlags(0) + if len(os.Args) != 3 { + log.Fatalf("Must specify two arguments, FROM and TO") + } + from := os.Args[1] + to := os.Args[2] + + out, err := exec.Command("git", "log", "--topo-order", "--pretty=tformat:%h %p|%s", "--reverse", fmt.Sprintf("%s..%s", from, to)).CombinedOutput() + if err != nil { + log.Fatal(err) + } + + hide := make(map[string]struct{}) + var apiChanges []string + var webconsole []string + var commits []commit + var upstreams []commit + var bumps []commit + for _, line := range strings.Split(string(out), "\n") { + if len(strings.TrimSpace(line)) == 0 { + continue + } + parts := strings.SplitN(line, "|", 2) + hashes := strings.Split(parts[0], " ") + c := commit{short: hashes[0], parents: hashes[1:], message: parts[1]} + + if strings.HasPrefix(c.message, "UPSTREAM: ") { + hide[c.short] = struct{}{} + upstreams = append(upstreams, c) + } + if strings.HasPrefix(c.message, "bump(") { + hide[c.short] = struct{}{} + bumps = append(bumps, c) + } + + if len(c.parents) == 1 { + commits = append(commits, c) + continue + } + + matches := mergeRequest.FindStringSubmatch(line) + if len(matches) == 0 { + // this may have been a human pressing the merge button, we'll just record this as a direct push + continue + } + + // split the accumulated commits into any that are force merges (assumed to be the initial set due + // to --topo-order) from the PR commits as soon as we see any of our merge parents. Then print + // any of the force merges + var first int + for i := range commits { + first = i + if contains(c.parents, commits[i].short) { + first++ + break + } + } + individual := commits[:first] + merged := commits[first:] + for _, commit := range individual { + if len(commit.parents) > 1 { + continue + } + if _, ok := hide[commit.short]; ok { + continue + } + fmt.Printf("force-merge: %s %s\n", commit.message, commit.short) + } + + // try to find either the PR title or the first commit title from the merge commit + out, err := exec.Command("git", "show", "--pretty=tformat:%b", c.short).CombinedOutput() + if err != nil { + log.Fatal(err) + } + var message string + para := strings.Split(string(out), "\n\n") + if len(para) > 0 && strings.HasPrefix(para[0], "Automatic merge from submit-queue") { + para = para[1:] + } + // this is no longer necessary with the submit queue in place + if len(para) > 0 && strings.HasPrefix(para[0], "Merged by ") { + para = para[1:] + } + // post submit-queue, the merge bot will add the PR title, which is usually pretty good + if len(para) > 0 { + message = strings.Split(para[0], "\n")[0] + } + if len(message) == 0 && len(merged) > 0 { + message = merged[0].message + } + if len(message) > 0 && len(merged) == 1 && message == merged[0].message { + merged = nil + } + + // try to calculate a prefix based on the diff + if len(message) > 0 && !prefix.MatchString(message) { + prefix, ok := findPrefixFor(message, merged) + if ok { + message = prefix + ": " + message + } + } + + // github merge + + // has api changes + display := fmt.Sprintf("%s [\\#%s](https://github.com/openimsdk/Open-IM-Server/pull/%s)", message, matches[1], matches[1]) + if hasFileChanges(c.short, "pkg/apistruct/") { + apiChanges = append(apiChanges, display) + } + + var filtered []commit + for _, commit := range merged { + if _, ok := hide[commit.short]; ok { + continue + } + filtered = append(filtered, commit) + } + if len(filtered) > 0 { + fmt.Printf("- %s\n", display) + for _, commit := range filtered { + fmt.Printf(" - %s (%s)\n", commit.message, commit.short) + } + } + + // stick the merge commit in at the beginning of the next list so we can anchor the previous parent + commits = []commit{c} + } + + // chunk the bumps + var lines []string + for _, commit := range bumps { + if m := webconsoleBump.FindStringSubmatch(commit.message); len(m) > 0 { + webconsole = append(webconsole, m[1]) + continue + } + lines = append(lines, commit.message) + } + lines = sortAndUniq(lines) + for _, line := range lines { + fmt.Printf("- %s\n", line) + } + + // chunk the upstreams + lines = nil + for _, commit := range upstreams { + lines = append(lines, commit.message) + } + lines = sortAndUniq(lines) + for _, line := range lines { + fmt.Printf("- %s\n", upstreamLinkify(line)) + } + + if len(webconsole) > 0 { + fmt.Printf("- web: from %s^..%s\n", webconsole[0], webconsole[len(webconsole)-1]) + } + + for _, apiChange := range apiChanges { + fmt.Printf(" - %s\n", apiChange) + } +} + +func findPrefixFor(message string, commits []commit) (string, bool) { + message = strings.ToLower(message) + for _, m := range assignments { + if strings.Contains(message, m.term) { + return m.prefix, true + } + } + for _, c := range commits { + if prefix, ok := findPrefixFor(c.message, nil); ok { + return prefix, ok + } + } + return "", false +} + +func hasFileChanges(commit string, prefixes ...string) bool { + out, err := exec.Command("git", "diff", "--name-only", fmt.Sprintf("%s^..%s", commit, commit)).CombinedOutput() + if err != nil { + log.Fatal(err) + } + for _, file := range strings.Split(string(out), "\n") { + for _, prefix := range prefixes { + if strings.HasPrefix(file, prefix) { + return true + } + } + } + return false +} + +func sortAndUniq(lines []string) []string { + sort.Strings(lines) + out := make([]string, 0, len(lines)) + last := "" + for _, s := range lines { + if last == s { + continue + } + last = s + out = append(out, s) + } + return out +} + +func upstreamLinkify(line string) string { + if m := upstreamKube.FindStringSubmatch(line); len(m) > 0 { + return fmt.Sprintf("UPSTREAM: [#%s](https://github.com/OpenIMSDK/Open-IM-Server/pull/%s):%s", m[1], m[1], m[2]) + } + if m := upstreamRepo.FindStringSubmatch(line); len(m) > 0 { + return fmt.Sprintf("UPSTREAM: [%s#%s](https://github.com/%s/pull/%s):%s", m[1], m[2], m[1], m[2], m[3]) + } + return line +} \ No newline at end of file diff --git a/tools/changelog/go.mod b/tools/changelog/go.mod new file mode 100644 index 000000000..319cdecec --- /dev/null +++ b/tools/changelog/go.mod @@ -0,0 +1,3 @@ +module github.com/OpenIMSDK/Open-IM-Server/tools/changelog + +go 1.20 diff --git a/tools/component/main.go b/tools/component/component.go similarity index 71% rename from tools/component/main.go rename to tools/component/component.go index db9ea915c..295ac44b1 100644 --- a/tools/component/main.go +++ b/tools/component/component.go @@ -1,8 +1,23 @@ +// 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 main import ( "context" "database/sql" + "flag" "fmt" "net" "net/url" @@ -29,7 +44,8 @@ import ( ) const ( - cfgPath = "../../../../../config/config.yaml" + // defaultCfgPath is the default path of the configuration file + defaultCfgPath = "../../../../../config/config.yaml" minioHealthCheckDuration = 1 maxRetry = 100 componentStartErrCode = 6000 @@ -37,84 +53,64 @@ const ( ) var ( + cfgPath = flag.String("c", defaultCfgPath, "Path to the configuration file") + ErrComponentStart = errs.NewCodeError(componentStartErrCode, "ComponentStartErr") ErrConfig = errs.NewCodeError(configErrCode, "Config file is incorrect") ) func initCfg() error { - data, err := os.ReadFile(cfgPath) + data, err := os.ReadFile(*cfgPath) if err != nil { return err } - if err = yaml.Unmarshal(data, &config.Config); err != nil { - return err - } - return nil + return yaml.Unmarshal(data, &config.Config) +} + +type checkFunc struct { + name string + function func() error } func main() { - err := initCfg() - if err != nil { - fmt.Printf("Read config failed: %v", err.Error()) + flag.Parse() + + if err := initCfg(); err != nil { + fmt.Printf("Read config failed: %v\n", err) + return } + + checks := []checkFunc{ + {name: "Mysql", function: checkMysql}, + {name: "Mongo", function: checkMongo}, + {name: "Minio", function: checkMinio}, + {name: "Redis", function: checkRedis}, + {name: "Zookeeper", function: checkZookeeper}, + {name: "Kafka", function: checkKafka}, + } + for i := 0; i < maxRetry; i++ { if i != 0 { time.Sleep(3 * time.Second) } - fmt.Printf("Checking components Round %v......\n", i+1) - // Check MySQL - if err := checkMysql(); err != nil { - errorPrint(fmt.Sprintf("Starting Mysql failed: %v. Please make sure your mysql service has started", err.Error())) - continue - } else { - successPrint(fmt.Sprint("Mysql starts successfully")) - } + fmt.Printf("Checking components Round %v...\n", i+1) - // Check MongoDB - if err := checkMongo(); err != nil { - errorPrint(fmt.Sprintf("Starting Mongo failed: %v. Please make sure your monngo service has started", err.Error())) - continue - } else { - successPrint(fmt.Sprint("Mongo starts successfully")) - } - - // Check Minio - if err := checkMinio(); err != nil { - if index := strings.Index(err.Error(), utils.IntToString(configErrCode)); index != -1 { - successPrint(fmt.Sprint("Minio starts successfully")) - warningPrint(fmt.Sprintf("%v. Please modify your config file", err.Error())) + allSuccess := true + for _, check := range checks { + err := check.function() + if err != nil { + errorPrint(fmt.Sprintf("Starting %s failed: %v", check.name, err)) + allSuccess = false + break } else { - errorPrint(fmt.Sprintf("Starting Minio failed: %v. Please make sure your Minio service has started", err.Error())) - continue + successPrint(fmt.Sprintf("%s starts successfully", check.name)) } - } else { - successPrint(fmt.Sprint("Minio starts successfully")) - } - // Check Redis - if err := checkRedis(); err != nil { - errorPrint(fmt.Sprintf("Starting Redis failed: %v.Please make sure your Redis service has started", err.Error())) - continue - } else { - successPrint(fmt.Sprint("Redis starts successfully")) } - // Check Zookeeper - if err := checkZookeeper(); err != nil { - errorPrint(fmt.Sprintf("Starting Zookeeper failed: %v.Please make sure your Zookeeper service has started", err.Error())) - continue - } else { - successPrint(fmt.Sprint("Zookeeper starts successfully")) + if allSuccess { + successPrint("All components started successfully!") + return } - - // Check Kafka - if err := checkKafka(); err != nil { - errorPrint(fmt.Sprintf("Starting Kafka failed: %v.Please make sure your Kafka service has started", err.Error())) - continue - } else { - successPrint(fmt.Sprint("Kafka starts successfully")) - } - successPrint(fmt.Sprint("All components starts successfully")) - os.Exit(0) } os.Exit(1) } @@ -207,8 +203,8 @@ func checkMinio() error { return ErrComponentStart.Wrap("Minio server is offline") } } - if exactIP(config.Config.Object.ApiURL) == "127.0.0.1" || exactIP(config.Config.Object.Minio.Endpoint) == "127.0.0.1" { - return ErrConfig.Wrap("apiURL or Minio endpoint contain 127.0.0.1.") + if exactIP(config.Config.Object.ApiURL) == "127.0.0.1" || exactIP(config.Config.Object.Minio.SignEndpoint) == "127.0.0.1" { + return ErrConfig.Wrap("apiURL or Minio SignEndpoint endpoint contain 127.0.0.1.") } } return nil diff --git a/tools/imctl/README.md b/tools/imctl/README.md new file mode 100644 index 000000000..d5f674b55 --- /dev/null +++ b/tools/imctl/README.md @@ -0,0 +1,47 @@ +# OpenIM CTL 模块 + + +## 为什么设计这个模块 + +OpenIM 后期功能扩展,不能总依赖一些单独的模块,而是整合到 Imctl 中。 + +测试同学做自动化测试或者是 e2e 测试,接口测试等等,每一次调用 API 很麻烦,用 imctl 的方式为 api 的调用提供了方便 + +和 scripts 深度交互,同样减少了 IM 本身的耦合度,提高了 IM 的可扩展性。 + + +## 功能设计 + ++ 用户管理:例如,添加、删除或禁用用户账户。 + ++ 系统监控:查看在线用户数量、消息传送速率等关键性能指标。 + ++ 调试:如查看日志、调整日志级别、查看系统状态等。 + ++ 配置管理:更新系统设置、管理插件或模块等。 + ++ 数据管理:备份和恢复数据、导入和导出数据等。 + ++ 系统维护:例如,执行更新、重启服务、进行维护模式等。 + + +## 设计思路 + +参考 kubectl, 方便 开发、运维、测试同学使用系统功能,并且实现自动化功能。 + +**自动化设计思路:** +1. 为后面的扩展子模块或者子命令提供自动化的功能,提供子命令 `imctl new` 自动创建新的子命令 +2. 以通过 imctl 对用户、密钥和策略进行CURD操作 +3. 设置 imctl 自动补全脚本 +4. 版本管理,问题:https://github.com/OpenIMSDK/Open-IM-Server/issues/574,做 IM 自动化的版本管理,查看 IM 系统版本 + +一些简单的 IM 解决方案可能不需要这样的工具,而复杂、高度定制的系统可能会从中受益。 + +所以暂时将这个模块放在 tools/imctl 中,后面迁移到 cmd/imctl 中 + + +## 目录结构设计 + +为了方便迁移,将 imctl 工程化设计,命令工具放入到 tools/imctl/cmd 中,其他的模块放入到 tools/imctl/pkg 中 + +``` \ No newline at end of file diff --git a/tools/imctl/cmd/genman/README.md b/tools/imctl/cmd/genman/README.md new file mode 100644 index 000000000..7b46cbefb --- /dev/null +++ b/tools/imctl/cmd/genman/README.md @@ -0,0 +1,49 @@ +# OpenIM `man` Module README + +Welcome to the `man` module of OpenIM, the comprehensive guide for using OpenIM's range of powerful commands. Here, you'll find in-depth details for each command, its options, and examples to help you harness the full power of the OpenIM suite. + +## Overview + +OpenIM is a robust instant messaging solution. To ensure users can effectively harness its capabilities, OpenIM provides a suite of commands that serve different functionalities, from the API level to RPC calls and utilities. + +The `man` module ensures that users, both new and experienced, have a reliable source of information and documentation to use these commands effectively. + +## Available Commands + +The OpenIM commands are divided into core services and tools. Below is a brief overview of each: + +### Core Services + +- **openim-api**: Interface to the main functionalities of OpenIM. +- **openim-cmdutils**: Utilities for executing common tasks. +- **openim-crontask**: Schedule and manage routine tasks within OpenIM. +- **openim-msggateway**: Gateway for managing messages within the OpenIM system. +- **openim-msgtransfer**: Handle message transfers across different parts of OpenIM. +- **openim-push**: Service for pushing notifications and updates. +- **openim-rpc-auth**: RPC interface for authentication tasks. +- **openim-rpc-conversation**: RPC service for handling conversations. +- **openim-rpc-friend**: Manage friend lists and related functionalities through RPC. +- **openim-rpc-group**: Group management via RPC. +- **openim-rpc-msg**: Message handling at the RPC level. +- **openim-rpc-third**: Third-party integrations and related tasks through RPC. +- **openim-rpc-user**: User management and tasks via RPC. + +### Tools + +- **changelog**: Track and manage changes in OpenIM. +- **component**: Utilities related to different components within OpenIM. +- **infra**: Infrastructure and backend management tools. +- **ncpu**: Monitor and manage CPU usage and related tasks. +- **yamlfmt**: A tool for formatting and linting YAML files within the OpenIM configuration. + +## How to Use + +To view the manual page for any of the OpenIM commands, use the `man` command followed by the command name. For example: + +``` +man openim-api +``` + +## Contributions + +We welcome contributions to enhance the `man` pages. If you discover inconsistencies, errors, or areas where further details are required, feel free to raise an issue or submit a pull request. \ No newline at end of file diff --git a/tools/imctl/cmd/genman/genman.go b/tools/imctl/cmd/genman/genman.go new file mode 100644 index 000000000..24aa97a13 --- /dev/null +++ b/tools/imctl/cmd/genman/genman.go @@ -0,0 +1,63 @@ +// 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 main + +import ( + "fmt" + "os" + + "k8s.io/kubernetes/cmd/genutils" +) + +func main() { + // TODO use os.Args instead of "flags" because "flags" will mess up the man pages! + path := "docs/man/man1" + module := "" + if len(os.Args) == 3 { + path = os.Args[1] + module = os.Args[2] + } else { + fmt.Fprintf(os.Stderr, "usage: %s [output directory] [module] \n", os.Args[0]) + os.Exit(1) + } + + outDir, err := genutils.OutDir(path) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to get output directory: %v\n", err) + os.Exit(1) + } + + // Set environment variables used by command so the output is consistent, + // regardless of where we run. + os.Setenv("HOME", "/home/username") + + // openim-api + // openim-cmdutils + // openim-crontask + // openim-msggateway + // openim-msgtransfer + // openim-push + // openim-rpc-auth + // openim-rpc-conversation + // openim-rpc-friend + // openim-rpc-group + // openim-rpc-msg + // openim-rpc-third + // openim-rpc-user + switch module { + case "openim-api": + + +} diff --git a/tools/imctl/cmd/imctl/imctl.go b/tools/imctl/cmd/imctl/imctl.go new file mode 100644 index 000000000..fea2023a9 --- /dev/null +++ b/tools/imctl/cmd/imctl/imctl.go @@ -0,0 +1,29 @@ +// 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. + +// iamctl is the command line tool for iam platform. +package main + +import ( + "os" + + "github.com/OpenIMSDK/Open-IM-Server/tools/imctl/internal/imctl/cmd" +) + +func main() { + command := cmd.NewDefaultIMCtlCommand() + if err := command.Execute(); err != nil { + os.Exit(1) + } +} diff --git a/tools/imctl/go.mod b/tools/imctl/go.mod new file mode 100644 index 000000000..ed3685f56 --- /dev/null +++ b/tools/imctl/go.mod @@ -0,0 +1,19 @@ +module github.com/OpenIMSDK/Open-IM-Server/tools/imctl + +go 1.20 + +require ( + github.com/MakeNowJust/heredoc/v2 v2.0.1 + github.com/marmotedu/iam v1.7.0 + github.com/mitchellh/go-wordwrap v1.0.1 + github.com/moby/term v0.5.0 + github.com/russross/blackfriday v1.6.0 + github.com/spf13/cobra v1.7.0 + github.com/spf13/pflag v1.0.5 +) + +require ( + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + golang.org/x/sys v0.1.0 // indirect +) diff --git a/tools/imctl/go.sum b/tools/imctl/go.sum new file mode 100644 index 000000000..05f38d414 --- /dev/null +++ b/tools/imctl/go.sum @@ -0,0 +1,26 @@ +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/MakeNowJust/heredoc/v2 v2.0.1 h1:rlCHh70XXXv7toz95ajQWOWQnN4WNLt0TdpZYIR/J6A= +github.com/MakeNowJust/heredoc/v2 v2.0.1/go.mod h1:6/2Abh5s+hc3g9nbWLe9ObDIOhaRrqsyY9MWy+4JdRM= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/marmotedu/iam v1.7.0 h1:9aWg5Enx+npHU9kxQ0eYsdXvbiGeUsuuzxaV49BQa0I= +github.com/marmotedu/iam v1.7.0/go.mod h1:kjQ1Tzr+M6/B49DSC3Zky+2Ai9vAr6PbhuHV8mWUS48= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= +github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/tools/imctl/internal/imctl/cmd/cmd.go b/tools/imctl/internal/imctl/cmd/cmd.go new file mode 100644 index 000000000..77a0ecb09 --- /dev/null +++ b/tools/imctl/internal/imctl/cmd/cmd.go @@ -0,0 +1,133 @@ +// 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 cmd + +import ( + "flag" + "io" + "os" + + "github.com/marmotedu/iam/pkg/cli/genericclioptions" + "github.com/spf13/cobra" + "github.com/spf13/viper" + "k8s.io/kubectl/pkg/cmd/completion" + "k8s.io/kubectl/pkg/cmd/options" + "k8s.io/kubectl/pkg/cmd/set" + "k8s.io/kubectl/pkg/cmd/version" + + "github.com/OpenIMSDK/Open-IM-Server/tools/imctl/internal/util/templates" +) + +// NewDefaultIAMCtlCommand creates the `imctl` command with default arguments. +func NewDefaultIMCtlCommand() *cobra.Command { + return NewIMCtlCommand(os.Stdin, os.Stdout, os.Stderr) +} + +// NewIAMCtlCommand returns new initialized instance of 'imctl' root command. +func NewIAMCtlCommand(in io.Reader, out, err io.Writer) *cobra.Command { + // Parent command to which all subcommands are added. + cmds := &cobra.Command{ + Use: "imctl", + Short: "imctl controls the IM platform", + Long: templates.LongDesc(` + imctl controls the IM platform, is the client side tool for IM platform. + + Find more information at: + // TODO: add link to docs, from auto scripts and gendocs + https://github.com/OpenIMSDK/Open-IM-Server/tree/main/docs`), + Run: runHelp, + // Hook before and after Run initialize and write profiles to disk, + // respectively. + PersistentPreRunE: func(*cobra.Command, []string) error { + return initProfiling() + }, + PersistentPostRunE: func(*cobra.Command, []string) error { + return flushProfiling() + }, + } + + flags := cmds.PersistentFlags() + flags.SetNormalizeFunc(cliflag.WarnWordSepNormalizeFunc) // Warn for "_" flags + + // Normalize all flags that are coming from other packages or pre-configurations + // a.k.a. change all "_" to "-". e.g. glog package + flags.SetNormalizeFunc(cliflag.WordSepNormalizeFunc) + + addProfilingFlags(flags) + + iamConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag().WithDeprecatedSecretFlag() + iamConfigFlags.AddFlags(flags) + matchVersionIAMConfigFlags := cmdutil.NewMatchVersionFlags(iamConfigFlags) + matchVersionIAMConfigFlags.AddFlags(cmds.PersistentFlags()) + + _ = viper.BindPFlags(cmds.PersistentFlags()) + cobra.OnInitialize(func() { + genericapiserver.LoadConfig(viper.GetString(genericclioptions.FlagIAMConfig), "iamctl") + }) + cmds.PersistentFlags().AddGoFlagSet(flag.CommandLine) + + f := cmdutil.NewFactory(matchVersionIAMConfigFlags) + + // From this point and forward we get warnings on flags that contain "_" separators + cmds.SetGlobalNormalizationFunc(cliflag.WarnWordSepNormalizeFunc) + + ioStreams := genericclioptions.IOStreams{In: in, Out: out, ErrOut: err} + + groups := templates.CommandGroups{ + { + Message: "Basic Commands:", + Commands: []*cobra.Command{ + info.NewCmdInfo(f, ioStreams), + color.NewCmdColor(f, ioStreams), + new.NewCmdNew(f, ioStreams), + jwt.NewCmdJWT(f, ioStreams), + }, + }, + { + Message: "Identity and Access Management Commands:", + Commands: []*cobra.Command{ + user.NewCmdUser(f, ioStreams), + secret.NewCmdSecret(f, ioStreams), + policy.NewCmdPolicy(f, ioStreams), + }, + }, + { + Message: "Troubleshooting and Debugging Commands:", + Commands: []*cobra.Command{ + validate.NewCmdValidate(f, ioStreams), + }, + }, + { + Message: "Settings Commands:", + Commands: []*cobra.Command{ + set.NewCmdSet(f, ioStreams), + completion.NewCmdCompletion(ioStreams.Out, ""), + }, + }, + } + groups.Add(cmds) + + filters := []string{"options"} + templates.ActsAsRootCommand(cmds, filters, groups...) + + cmds.AddCommand(version.NewCmdVersion(f, ioStreams)) + cmds.AddCommand(options.NewCmdOptions(ioStreams.Out)) + + return cmds +} + +func runHelp(cmd *cobra.Command, args []string) { + _ = cmd.Help() +} diff --git a/tools/imctl/internal/imctl/cmd/profiling.go b/tools/imctl/internal/imctl/cmd/profiling.go new file mode 100644 index 000000000..eaf9acceb --- /dev/null +++ b/tools/imctl/internal/imctl/cmd/profiling.go @@ -0,0 +1,95 @@ +// 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 cmd + +import ( + "errors" + "fmt" + "os" + "runtime" + "runtime/pprof" + + "github.com/spf13/pflag" +) + +// profiling configuration variables +var ( + profileName string = "none" // Name of the profile to capture. + profileOutput string = "profile.pprof" // File to write the profile data. +) + +// addProfilingFlags registers profiling related flags to the given FlagSet. +func addProfilingFlags(flags *pflag.FlagSet) { + flags.StringVar( + &profileName, + "profile", + "none", + "Type of profile to capture. Options: none, cpu, heap, goroutine, threadcreate, block, mutex", + ) + flags.StringVar(&profileOutput, "profile-output", "profile.pprof", "File to write the profile data") +} + +// initProfiling sets up profiling based on the user's choice. +// If 'cpu' is selected, it starts the CPU profile. For block and mutex profiles, +// sampling rates are set up. +func initProfiling() error { + switch profileName { + case "none": + return nil + case "cpu": + f, err := os.Create(profileOutput) + if err != nil { + return err + } + return pprof.StartCPUProfile(f) + case "block": + runtime.SetBlockProfileRate(1) // Sampling every block event + return nil + case "mutex": + runtime.SetMutexProfileFraction(1) // Sampling every mutex event + return nil + default: + if profile := pprof.Lookup(profileName); profile == nil { + return fmt.Errorf("unknown profile type: '%s'", profileName) + } + return nil + } +} + +// flushProfiling writes the profiling data to the specified file. +// For heap profiles, it runs the GC before capturing the data. +// It stops the CPU profile if it was started. +func flushProfiling() error { + switch profileName { + case "none": + return nil + case "cpu": + pprof.StopCPUProfile() + return nil + case "heap": + runtime.GC() // Run garbage collection before writing heap profile + fallthrough + default: + profile := pprof.Lookup(profileName) + if profile == nil { + return errors.New("invalid profile type") + } + f, err := os.Create(profileOutput) + if err != nil { + return err + } + return profile.WriteTo(f, 0) + } +} diff --git a/tools/imctl/internal/imctl/util/interrupt/interrupt.go b/tools/imctl/internal/imctl/util/interrupt/interrupt.go new file mode 100644 index 000000000..e1d8386de --- /dev/null +++ b/tools/imctl/internal/imctl/util/interrupt/interrupt.go @@ -0,0 +1,103 @@ +// 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 interrupt deal with signals. +package interrupt + +import ( + "os" + "os/signal" + "sync" + "syscall" +) + +// terminationSignals are signals that cause the program to exit in the +// supported platforms (linux, darwin, windows). +var terminationSignals = []os.Signal{syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT} + +// Handler guarantees execution of notifications after a critical section (the function passed +// to a Run method), even in the presence of process termination. It guarantees exactly once +// invocation of the provided notify functions. +type Handler struct { + notify []func() + final func(os.Signal) + once sync.Once +} + +// Chain creates a new handler that invokes all notify functions when the critical section exits +// and then invokes the optional handler's notifications. This allows critical sections to be +// nested without losing exactly once invocations. Notify functions can invoke any cleanup needed +// but should not exit (which is the responsibility of the parent handler). +func Chain(handler *Handler, notify ...func()) *Handler { + if handler == nil { + return New(nil, notify...) + } + return New(handler.Signal, append(notify, handler.Close)...) +} + +// New creates a new handler that guarantees all notify functions are run after the critical +// section exits (or is interrupted by the OS), then invokes the final handler. If no final +// handler is specified, the default final is `os.Exit(1)`. A handler can only be used for +// one critical section. +func New(final func(os.Signal), notify ...func()) *Handler { + return &Handler{ + final: final, + notify: notify, + } +} + +// Close executes all the notification handlers if they have not yet been executed. +func (h *Handler) Close() { + h.once.Do(func() { + for _, fn := range h.notify { + fn() + } + }) +} + +// Signal is called when an os.Signal is received, and guarantees that all notifications +// are executed, then the final handler is executed. This function should only be called once +// per Handler instance. +func (h *Handler) Signal(s os.Signal) { + h.once.Do(func() { + for _, fn := range h.notify { + fn() + } + if h.final == nil { + os.Exit(1) + } + h.final(s) + }) +} + +// Run ensures that any notifications are invoked after the provided fn exits (even if the +// process is interrupted by an OS termination signal). Notifications are only invoked once +// per Handler instance, so calling Run more than once will not behave as the user expects. +func (h *Handler) Run(fn func() error) error { + ch := make(chan os.Signal, 1) + signal.Notify(ch, terminationSignals...) + defer func() { + signal.Stop(ch) + close(ch) + }() + go func() { + sig, ok := <-ch + if !ok { + return + } + h.Signal(sig) + }() + defer h.Close() + return fn() +} diff --git a/tools/imctl/internal/imctl/util/templates/command_groups.go b/tools/imctl/internal/imctl/util/templates/command_groups.go new file mode 100644 index 000000000..538b43ac4 --- /dev/null +++ b/tools/imctl/internal/imctl/util/templates/command_groups.go @@ -0,0 +1,57 @@ +// 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 templates + +import ( + "github.com/spf13/cobra" +) + +type CommandGroup struct { + Message string + Commands []*cobra.Command +} + +type CommandGroups []CommandGroup + +func (g CommandGroups) Add(c *cobra.Command) { + for _, group := range g { + c.AddCommand(group.Commands...) + } +} + +func (g CommandGroups) Has(c *cobra.Command) bool { + for _, group := range g { + for _, command := range group.Commands { + if command == c { + return true + } + } + } + return false +} + +func AddAdditionalCommands(g CommandGroups, message string, cmds []*cobra.Command) CommandGroups { + group := CommandGroup{Message: message} + for _, c := range cmds { + // Don't show commands that have no short description + if !g.Has(c) && len(c.Short) != 0 { + group.Commands = append(group.Commands, c) + } + } + if len(group.Commands) == 0 { + return g + } + return append(g, group) +} diff --git a/tools/imctl/internal/imctl/util/templates/markdown.go b/tools/imctl/internal/imctl/util/templates/markdown.go new file mode 100644 index 000000000..5621163f8 --- /dev/null +++ b/tools/imctl/internal/imctl/util/templates/markdown.go @@ -0,0 +1,149 @@ +// 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 templates + +import ( + "bytes" + "fmt" + "io" + "strings" + + "github.com/russross/blackfriday" +) + +const linebreak = "\n" + +// ASCIIRenderer implements blackfriday.Renderer. +var _ blackfriday.Renderer = &ASCIIRenderer{} + +// ASCIIRenderer is a blackfriday.Renderer intended for rendering markdown +// documents as plain text, well suited for human reading on terminals. +type ASCIIRenderer struct { + Indentation string + + listItemCount uint + listLevel uint +} + +// NormalText gets a text chunk *after* the markdown syntax was already +// processed and does a final cleanup on things we don't expect here, like +// removing linebreaks on things that are not a paragraph break (auto unwrap). +func (r *ASCIIRenderer) NormalText(out *bytes.Buffer, text []byte) { + raw := string(text) + lines := strings.Split(raw, linebreak) + for _, line := range lines { + trimmed := strings.Trim(line, " \n\t") + if len(trimmed) > 0 && trimmed[0] != '_' { + out.WriteString(" ") + } + out.WriteString(trimmed) + } +} + +// List renders the start and end of a list. +func (r *ASCIIRenderer) List(out *bytes.Buffer, text func() bool, flags int) { + r.listLevel++ + out.WriteString(linebreak) + text() + r.listLevel-- +} + +// ListItem renders list items and supports both ordered and unordered lists. +func (r *ASCIIRenderer) ListItem(out *bytes.Buffer, text []byte, flags int) { + if flags&blackfriday.LIST_ITEM_BEGINNING_OF_LIST != 0 { + r.listItemCount = 1 + } else { + r.listItemCount++ + } + indent := strings.Repeat(r.Indentation, int(r.listLevel)) + var bullet string + if flags&blackfriday.LIST_TYPE_ORDERED != 0 { + bullet += fmt.Sprintf("%d.", r.listItemCount) + } else { + bullet += "*" + } + out.WriteString(indent + bullet + " ") + r.fw(out, text) + out.WriteString(linebreak) +} + +// Paragraph renders the start and end of a paragraph. +func (r *ASCIIRenderer) Paragraph(out *bytes.Buffer, text func() bool) { + out.WriteString(linebreak) + text() + out.WriteString(linebreak) +} + +// BlockCode renders a chunk of text that represents source code. +func (r *ASCIIRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string) { + out.WriteString(linebreak) + lines := []string{} + for _, line := range strings.Split(string(text), linebreak) { + indented := r.Indentation + line + lines = append(lines, indented) + } + out.WriteString(strings.Join(lines, linebreak)) +} + +func (r *ASCIIRenderer) GetFlags() int { return 0 } +func (r *ASCIIRenderer) HRule(out *bytes.Buffer) { + out.WriteString(linebreak + "----------" + linebreak) +} +func (r *ASCIIRenderer) LineBreak(out *bytes.Buffer) { out.WriteString(linebreak) } +func (r *ASCIIRenderer) TitleBlock(out *bytes.Buffer, text []byte) { r.fw(out, text) } +func (r *ASCIIRenderer) Header(out *bytes.Buffer, text func() bool, level int, id string) { text() } +func (r *ASCIIRenderer) BlockHtml(out *bytes.Buffer, text []byte) { r.fw(out, text) } +func (r *ASCIIRenderer) BlockQuote(out *bytes.Buffer, text []byte) { r.fw(out, text) } +func (r *ASCIIRenderer) TableRow(out *bytes.Buffer, text []byte) { r.fw(out, text) } +func (r *ASCIIRenderer) TableHeaderCell(out *bytes.Buffer, text []byte, align int) { r.fw(out, text) } +func (r *ASCIIRenderer) TableCell(out *bytes.Buffer, text []byte, align int) { r.fw(out, text) } +func (r *ASCIIRenderer) Footnotes(out *bytes.Buffer, text func() bool) { text() } +func (r *ASCIIRenderer) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) { + r.fw(out, text) +} +func (r *ASCIIRenderer) AutoLink(out *bytes.Buffer, link []byte, kind int) { r.fw(out, link) } +func (r *ASCIIRenderer) CodeSpan(out *bytes.Buffer, text []byte) { r.fw(out, text) } +func (r *ASCIIRenderer) DoubleEmphasis(out *bytes.Buffer, text []byte) { r.fw(out, text) } +func (r *ASCIIRenderer) Emphasis(out *bytes.Buffer, text []byte) { r.fw(out, text) } +func (r *ASCIIRenderer) RawHtmlTag(out *bytes.Buffer, text []byte) { r.fw(out, text) } +func (r *ASCIIRenderer) TripleEmphasis(out *bytes.Buffer, text []byte) { r.fw(out, text) } +func (r *ASCIIRenderer) StrikeThrough(out *bytes.Buffer, text []byte) { r.fw(out, text) } +func (r *ASCIIRenderer) FootnoteRef(out *bytes.Buffer, ref []byte, id int) { r.fw(out, ref) } +func (r *ASCIIRenderer) Entity(out *bytes.Buffer, entity []byte) { r.fw(out, entity) } +func (r *ASCIIRenderer) Smartypants(out *bytes.Buffer, text []byte) { r.fw(out, text) } +func (r *ASCIIRenderer) DocumentHeader(out *bytes.Buffer) {} +func (r *ASCIIRenderer) DocumentFooter(out *bytes.Buffer) {} +func (r *ASCIIRenderer) TocHeaderWithAnchor(text []byte, level int, anchor string) {} +func (r *ASCIIRenderer) TocHeader(text []byte, level int) {} +func (r *ASCIIRenderer) TocFinalize() {} + +func (r *ASCIIRenderer) Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) { + r.fw(out, header, body) +} + +func (r *ASCIIRenderer) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) { + out.WriteString(" ") + r.fw(out, link) +} + +func (r *ASCIIRenderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) { + r.fw(out, link) +} + +func (r *ASCIIRenderer) fw(out io.Writer, text ...[]byte) { + for _, t := range text { + out.Write(t) + } +} diff --git a/tools/imctl/internal/imctl/util/templates/normalizers.go b/tools/imctl/internal/imctl/util/templates/normalizers.go new file mode 100644 index 000000000..f5873a0be --- /dev/null +++ b/tools/imctl/internal/imctl/util/templates/normalizers.go @@ -0,0 +1,99 @@ +// 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 templates + +import ( + "strings" + + "github.com/MakeNowJust/heredoc/v2" + "github.com/russross/blackfriday" + "github.com/spf13/cobra" +) + +const Indentation = ` ` + +// LongDesc normalizes a command's long description to follow the conventions. +func LongDesc(s string) string { + if len(s) == 0 { + return s + } + return normalizer{s}.heredoc().markdown().trim().string +} + +// Examples normalizes a command's examples to follow the conventions. +func Examples(s string) string { + if len(s) == 0 { + return s + } + return normalizer{s}.trim().indent().string +} + +// Normalize perform all required normalizations on a given command. +func Normalize(cmd *cobra.Command) *cobra.Command { + if len(cmd.Long) > 0 { + cmd.Long = LongDesc(cmd.Long) + } + if len(cmd.Example) > 0 { + cmd.Example = Examples(cmd.Example) + } + return cmd +} + +// NormalizeAll perform all required normalizations in the entire command tree. +func NormalizeAll(cmd *cobra.Command) *cobra.Command { + if cmd.HasSubCommands() { + for _, subCmd := range cmd.Commands() { + NormalizeAll(subCmd) + } + } + Normalize(cmd) + return cmd +} + +type normalizer struct { + string +} + +func (s normalizer) markdown() normalizer { + bytes := []byte(s.string) + formatted := blackfriday.Markdown( + bytes, + &ASCIIRenderer{Indentation: Indentation}, + blackfriday.EXTENSION_NO_INTRA_EMPHASIS, + ) + s.string = string(formatted) + return s +} + +func (s normalizer) heredoc() normalizer { + s.string = heredoc.Doc(s.string) + return s +} + +func (s normalizer) trim() normalizer { + s.string = strings.TrimSpace(s.string) + return s +} + +func (s normalizer) indent() normalizer { + indentedLines := []string{} + for _, line := range strings.Split(s.string, "\n") { + trimmed := strings.TrimSpace(line) + indented := Indentation + trimmed + indentedLines = append(indentedLines, indented) + } + s.string = strings.Join(indentedLines, "\n") + return s +} diff --git a/tools/imctl/internal/imctl/util/templates/templater.go b/tools/imctl/internal/imctl/util/templates/templater.go new file mode 100644 index 000000000..7b75cef13 --- /dev/null +++ b/tools/imctl/internal/imctl/util/templates/templater.go @@ -0,0 +1,296 @@ +// 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 templates + +import ( + "bytes" + "fmt" + "strings" + "text/template" + "unicode" + + "github.com/spf13/cobra" + flag "github.com/spf13/pflag" + + "github.com/OpenIMSDK/Open-IM-Server/tools/imctl/internal/util/term" +) + +type FlagExposer interface { + ExposeFlags(cmd *cobra.Command, flags ...string) FlagExposer +} + +func ActsAsRootCommand(cmd *cobra.Command, filters []string, groups ...CommandGroup) FlagExposer { + if cmd == nil { + panic("nil root command") + } + templater := &templater{ + RootCmd: cmd, + UsageTemplate: MainUsageTemplate(), + HelpTemplate: MainHelpTemplate(), + CommandGroups: groups, + Filtered: filters, + } + cmd.SetFlagErrorFunc(templater.FlagErrorFunc()) + cmd.SilenceUsage = true + cmd.SetUsageFunc(templater.UsageFunc()) + cmd.SetHelpFunc(templater.HelpFunc()) + return templater +} + +func UseOptionsTemplates(cmd *cobra.Command) { + templater := &templater{ + UsageTemplate: OptionsUsageTemplate(), + HelpTemplate: OptionsHelpTemplate(), + } + cmd.SetUsageFunc(templater.UsageFunc()) + cmd.SetHelpFunc(templater.HelpFunc()) +} + +type templater struct { + UsageTemplate string + HelpTemplate string + RootCmd *cobra.Command + CommandGroups + Filtered []string +} + +func (t *templater) FlagErrorFunc(exposedFlags ...string) func(*cobra.Command, error) error { + return func(c *cobra.Command, err error) error { + c.SilenceUsage = true + switch c.CalledAs() { + case "options": + return fmt.Errorf("%s\nrun '%s' without flags", err, c.CommandPath()) + default: + return fmt.Errorf("%s\nsee '%s --help' for usage", err, c.CommandPath()) + } + } +} + +func (t *templater) ExposeFlags(cmd *cobra.Command, flags ...string) FlagExposer { + cmd.SetUsageFunc(t.UsageFunc(flags...)) + return t +} + +func (t *templater) HelpFunc() func(*cobra.Command, []string) { + return func(c *cobra.Command, s []string) { + tt := template.New("help") + tt.Funcs(t.templateFuncs()) + template.Must(tt.Parse(t.HelpTemplate)) + out := term.NewResponsiveWriter(c.OutOrStdout()) + err := tt.Execute(out, c) + if err != nil { + c.Println(err) + } + } +} + +func (t *templater) UsageFunc(exposedFlags ...string) func(*cobra.Command) error { + return func(c *cobra.Command) error { + tt := template.New("usage") + tt.Funcs(t.templateFuncs(exposedFlags...)) + template.Must(tt.Parse(t.UsageTemplate)) + out := term.NewResponsiveWriter(c.OutOrStderr()) + return tt.Execute(out, c) + } +} + +func (t *templater) templateFuncs(exposedFlags ...string) template.FuncMap { + return template.FuncMap{ + "trim": strings.TrimSpace, + "trimRight": func(s string) string { return strings.TrimRightFunc(s, unicode.IsSpace) }, + "trimLeft": func(s string) string { return strings.TrimLeftFunc(s, unicode.IsSpace) }, + "gt": cobra.Gt, + "eq": cobra.Eq, + "rpad": rpad, + "appendIfNotPresent": appendIfNotPresent, + "flagsNotIntersected": flagsNotIntersected, + "visibleFlags": visibleFlags, + "flagsUsages": flagsUsages, + "cmdGroups": t.cmdGroups, + "cmdGroupsString": t.cmdGroupsString, + "rootCmd": t.rootCmdName, + "isRootCmd": t.isRootCmd, + "optionsCmdFor": t.optionsCmdFor, + "usageLine": t.usageLine, + "exposed": func(c *cobra.Command) *flag.FlagSet { + exposed := flag.NewFlagSet("exposed", flag.ContinueOnError) + if len(exposedFlags) > 0 { + for _, name := range exposedFlags { + if flag := c.Flags().Lookup(name); flag != nil { + exposed.AddFlag(flag) + } + } + } + return exposed + }, + } +} + +func (t *templater) cmdGroups(c *cobra.Command, all []*cobra.Command) []CommandGroup { + if len(t.CommandGroups) > 0 && c == t.RootCmd { + all = filter(all, t.Filtered...) + return AddAdditionalCommands(t.CommandGroups, "Other Commands:", all) + } + all = filter(all, "options") + return []CommandGroup{ + { + Message: "Available Commands:", + Commands: all, + }, + } +} + +func (t *templater) cmdGroupsString(c *cobra.Command) string { + groups := []string{} + for _, cmdGroup := range t.cmdGroups(c, c.Commands()) { + cmds := []string{cmdGroup.Message} + for _, cmd := range cmdGroup.Commands { + if cmd.IsAvailableCommand() { + cmds = append(cmds, " "+rpad(cmd.Name(), cmd.NamePadding())+" "+cmd.Short) + } + } + groups = append(groups, strings.Join(cmds, "\n")) + } + return strings.Join(groups, "\n\n") +} + +func (t *templater) rootCmdName(c *cobra.Command) string { + return t.rootCmd(c).CommandPath() +} + +func (t *templater) isRootCmd(c *cobra.Command) bool { + return t.rootCmd(c) == c +} + +func (t *templater) parents(c *cobra.Command) []*cobra.Command { + parents := []*cobra.Command{c} + for current := c; !t.isRootCmd(current) && current.HasParent(); { + current = current.Parent() + parents = append(parents, current) + } + return parents +} + +func (t *templater) rootCmd(c *cobra.Command) *cobra.Command { + if c != nil && !c.HasParent() { + return c + } + if t.RootCmd == nil { + panic("nil root cmd") + } + return t.RootCmd +} + +func (t *templater) optionsCmdFor(c *cobra.Command) string { + if !c.Runnable() { + return "" + } + rootCmdStructure := t.parents(c) + for i := len(rootCmdStructure) - 1; i >= 0; i-- { + cmd := rootCmdStructure[i] + if _, _, err := cmd.Find([]string{"options"}); err == nil { + return cmd.CommandPath() + " options" + } + } + return "" +} + +func (t *templater) usageLine(c *cobra.Command) string { + usage := c.UseLine() + suffix := "[options]" + if c.HasFlags() && !strings.Contains(usage, suffix) { + usage += " " + suffix + } + return usage +} + +func flagsUsages(f *flag.FlagSet) string { + x := new(bytes.Buffer) + + f.VisitAll(func(flag *flag.Flag) { + if flag.Hidden { + return + } + format := "--%s=%s: %s\n" + + if flag.Value.Type() == "string" { + format = "--%s='%s': %s\n" + } + + if len(flag.Shorthand) > 0 { + format = " -%s, " + format + } else { + format = " %s " + format + } + + fmt.Fprintf(x, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage) + }) + + return x.String() +} + +func rpad(s string, padding int) string { + template := fmt.Sprintf("%%-%ds", padding) + return fmt.Sprintf(template, s) +} + +func appendIfNotPresent(s, stringToAppend string) string { + if strings.Contains(s, stringToAppend) { + return s + } + return s + " " + stringToAppend +} + +func flagsNotIntersected(l *flag.FlagSet, r *flag.FlagSet) *flag.FlagSet { + f := flag.NewFlagSet("notIntersected", flag.ContinueOnError) + l.VisitAll(func(flag *flag.Flag) { + if r.Lookup(flag.Name) == nil { + f.AddFlag(flag) + } + }) + return f +} + +func visibleFlags(l *flag.FlagSet) *flag.FlagSet { + hidden := "help" + f := flag.NewFlagSet("visible", flag.ContinueOnError) + l.VisitAll(func(flag *flag.Flag) { + if flag.Name != hidden { + f.AddFlag(flag) + } + }) + return f +} + +func filter(cmds []*cobra.Command, names ...string) []*cobra.Command { + out := []*cobra.Command{} + for _, c := range cmds { + if c.Hidden { + continue + } + skip := false + for _, name := range names { + if name == c.Name() { + skip = true + break + } + } + if skip { + continue + } + out = append(out, c) + } + return out +} diff --git a/tools/imctl/internal/imctl/util/templates/templates.go b/tools/imctl/internal/imctl/util/templates/templates.go new file mode 100644 index 000000000..ec71434ce --- /dev/null +++ b/tools/imctl/internal/imctl/util/templates/templates.go @@ -0,0 +1,103 @@ +// 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 templates provides template functions for working with templates. +package templates + +import ( + "strings" + "unicode" +) + +const ( + // SectionVars is the help template section that declares variables to be used in the template. + SectionVars = `{{$isRootCmd := isRootCmd .}}` + + `{{$rootCmd := rootCmd .}}` + + `{{$visibleFlags := visibleFlags (flagsNotIntersected .LocalFlags .PersistentFlags)}}` + + `{{$explicitlyExposedFlags := exposed .}}` + + `{{$optionsCmdFor := optionsCmdFor .}}` + + `{{$usageLine := usageLine .}}` + + // SectionAliases is the help template section that displays command aliases. + SectionAliases = `{{if gt .Aliases 0}}Aliases: +{{.NameAndAliases}} + +{{end}}` + + // SectionExamples is the help template section that displays command examples. + SectionExamples = `{{if .HasExample}}Examples: +{{trimRight .Example}} + +{{end}}` + + // SectionSubcommands is the help template section that displays the command's subcommands. + SectionSubcommands = `{{if .HasAvailableSubCommands}}{{cmdGroupsString .}} + +{{end}}` + + // SectionFlags is the help template section that displays the command's flags. + SectionFlags = `{{ if or $visibleFlags.HasFlags $explicitlyExposedFlags.HasFlags}}Options: +{{ if $visibleFlags.HasFlags}}{{trimRight (flagsUsages $visibleFlags)}}{{end}}{{ if $explicitlyExposedFlags.HasFlags}}{{ if $visibleFlags.HasFlags}} +{{end}}{{trimRight (flagsUsages $explicitlyExposedFlags)}}{{end}} + +{{end}}` + + // SectionUsage is the help template section that displays the command's usage. + SectionUsage = `{{if and .Runnable (ne .UseLine "") (ne .UseLine $rootCmd)}}Usage: + {{$usageLine}} + +{{end}}` + + // SectionTipsHelp is the help template section that displays the '--help' hint. + SectionTipsHelp = `{{if .HasSubCommands}}Use "{{$rootCmd}} --help" for more information about a given command. +{{end}}` + + // SectionTipsGlobalOptions is the help template section that displays the 'options' hint for displaying global + // flags. + SectionTipsGlobalOptions = `{{if $optionsCmdFor}}Use "{{$optionsCmdFor}}" for a list of global command-line options (applies to all commands). +{{end}}` +) + +// MainHelpTemplate if the template for 'help' used by most commands. +func MainHelpTemplate() string { + return `{{with or .Long .Short }}{{. | trim}}{{end}}{{if or .Runnable .HasSubCommands}}{{.UsageString}}{{end}}` +} + +// MainUsageTemplate if the template for 'usage' used by most commands. +func MainUsageTemplate() string { + sections := []string{ + "\n\n", + SectionVars, + SectionAliases, + SectionExamples, + SectionSubcommands, + SectionFlags, + SectionUsage, + SectionTipsHelp, + SectionTipsGlobalOptions, + } + return strings.TrimRightFunc(strings.Join(sections, ""), unicode.IsSpace) +} + +// OptionsHelpTemplate if the template for 'help' used by the 'options' command. +func OptionsHelpTemplate() string { + return "" +} + +// OptionsUsageTemplate if the template for 'usage' used by the 'options' command. +func OptionsUsageTemplate() string { + return `{{ if .HasInheritedFlags}}The following options can be passed to any command: + +{{flagsUsages .InheritedFlags}}{{end}}` +} diff --git a/tools/imctl/internal/imctl/util/term/resize.go b/tools/imctl/internal/imctl/util/term/resize.go new file mode 100644 index 000000000..0063d0723 --- /dev/null +++ b/tools/imctl/internal/imctl/util/term/resize.go @@ -0,0 +1,53 @@ +// 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 term + +import ( + "github.com/moby/term" +) + +// TerminalSize represents the width and height of a terminal. +type TerminalSize struct { + Width uint16 + Height uint16 +} + +// TerminalSizeQueue is capable of returning terminal resize events as they occur. +type TerminalSizeQueue interface { + // Next returns the new terminal size after the terminal has been resized. It returns nil when + // monitoring has been stopped. + Next() *TerminalSize +} + +// GetSize returns the current size of the user's terminal. If it isn't a terminal, +// nil is returned. +func (t TTY) GetSize() *TerminalSize { + outFd, isTerminal := term.GetFdInfo(t.Out) + if !isTerminal { + return nil + } + return GetSize(outFd) +} + +// GetSize returns the current size of the terminal associated with fd. +func GetSize(fd uintptr) *TerminalSize { + winsize, err := term.GetWinsize(fd) + if err != nil { + // runtime.HandleError(fmt.Errorf("unable to get terminal size: %v", err)) + return nil + } + + return &TerminalSize{Width: winsize.Width, Height: winsize.Height} +} diff --git a/tools/imctl/internal/imctl/util/term/term.go b/tools/imctl/internal/imctl/util/term/term.go new file mode 100644 index 000000000..45c820384 --- /dev/null +++ b/tools/imctl/internal/imctl/util/term/term.go @@ -0,0 +1,37 @@ +// 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 term provides structures and helper functions to work with +// terminal (state, sizes). +package term + +import ( + "io" +) + +// TTY helps invoke a function and preserve the state of the terminal, even if the process is +// terminated during execution. It also provides support for terminal resizing for remote command +// execution/attachment. +type TTY struct { + // In is a reader representing stdin. It is a required field. + In io.Reader + // Out is a writer representing stdout. It must be set to support terminal resizing. It is an + // optional field. + Out io.Writer + // Raw is true if the terminal should be set raw. + Raw bool + // TryDev indicates the TTY should try to open /dev/tty if the provided input + // is not a file descriptor. + TryDev bool +} diff --git a/tools/imctl/internal/imctl/util/term/term_writer.go b/tools/imctl/internal/imctl/util/term/term_writer.go new file mode 100644 index 000000000..700a223af --- /dev/null +++ b/tools/imctl/internal/imctl/util/term/term_writer.go @@ -0,0 +1,124 @@ +// 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 term + +import ( + "io" + "os" + + wordwrap "github.com/mitchellh/go-wordwrap" + "github.com/moby/term" +) + +type wordWrapWriter struct { + limit uint + writer io.Writer +} + +// NewResponsiveWriter creates a Writer that detects the column width of the +// terminal we are in, and adjusts every line width to fit and use recommended +// terminal sizes for better readability. Does proper word wrapping automatically. +// +// if terminal width >= 120 columns use 120 columns +// if terminal width >= 100 columns use 100 columns +// if terminal width >= 80 columns use 80 columns +// +// In case we're not in a terminal or if it's smaller than 80 columns width, +// doesn't do any wrapping. +func NewResponsiveWriter(w io.Writer) io.Writer { + file, ok := w.(*os.File) + if !ok { + return w + } + fd := file.Fd() + if !term.IsTerminal(fd) { + return w + } + + terminalSize := GetSize(fd) + if terminalSize == nil { + return w + } + + var limit uint + switch { + case terminalSize.Width >= 120: + limit = 120 + case terminalSize.Width >= 100: + limit = 100 + case terminalSize.Width >= 80: + limit = 80 + } + + return NewWordWrapWriter(w, limit) +} + +// NewWordWrapWriter is a Writer that supports a limit of characters on every line +// and does auto word wrapping that respects that limit. +func NewWordWrapWriter(w io.Writer, limit uint) io.Writer { + return &wordWrapWriter{ + limit: limit, + writer: w, + } +} + +func (w wordWrapWriter) Write(p []byte) (nn int, err error) { + if w.limit == 0 { + return w.writer.Write(p) + } + original := string(p) + wrapped := wordwrap.WrapString(original, w.limit) + return w.writer.Write([]byte(wrapped)) +} + +// NewPunchCardWriter is a NewWordWrapWriter that limits the line width to 80 columns. +func NewPunchCardWriter(w io.Writer) io.Writer { + return NewWordWrapWriter(w, 80) +} + +type maxWidthWriter struct { + maxWidth uint + currentWidth uint + written uint + writer io.Writer +} + +// NewMaxWidthWriter is a Writer that supports a limit of characters on every +// line, but doesn't do any word wrapping automatically. +func NewMaxWidthWriter(w io.Writer, maxWidth uint) io.Writer { + return &maxWidthWriter{ + maxWidth: maxWidth, + writer: w, + } +} + +func (m maxWidthWriter) Write(p []byte) (nn int, err error) { + for _, b := range p { + if m.currentWidth == m.maxWidth { + m.writer.Write([]byte{'\n'}) + m.currentWidth = 0 + } + if b == '\n' { + m.currentWidth = 0 + } + _, err := m.writer.Write([]byte{b}) + if err != nil { + return int(m.written), err + } + m.written++ + m.currentWidth++ + } + return len(p), nil +} diff --git a/tools/imctl/internal/imctl/util/term/term_writer_test.go b/tools/imctl/internal/imctl/util/term/term_writer_test.go new file mode 100644 index 000000000..588ba3418 --- /dev/null +++ b/tools/imctl/internal/imctl/util/term/term_writer_test.go @@ -0,0 +1,114 @@ +// 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 term + +import ( + "bytes" + "strings" + "testing" +) + +const test = "Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam Iam" + +func TestWordWrapWriter(t *testing.T) { + testcases := map[string]struct { + input string + maxWidth uint + }{ + "max 10": {input: test, maxWidth: 10}, + "max 80": {input: test, maxWidth: 80}, + "max 120": {input: test, maxWidth: 120}, + "max 5000": {input: test, maxWidth: 5000}, + } + for k, tc := range testcases { + b := bytes.NewBufferString("") + w := NewWordWrapWriter(b, tc.maxWidth) + _, err := w.Write([]byte(tc.input)) + if err != nil { + t.Errorf("%s: Unexpected error: %v", k, err) + } + result := b.String() + if !strings.Contains(result, "Iam") { + t.Errorf("%s: Expected to contain \"Iam\"", k) + } + if len(result) < len(tc.input) { + t.Errorf( + "%s: Unexpectedly short string, got %d wanted at least %d chars: %q", + k, + len(result), + len(tc.input), + result, + ) + } + for _, line := range strings.Split(result, "\n") { + if len(line) > int(tc.maxWidth) { + t.Errorf("%s: Every line must be at most %d chars long, got %d: %q", k, tc.maxWidth, len(line), line) + } + } + for _, word := range strings.Split(result, " ") { + if !strings.Contains(word, "Iam") { + t.Errorf("%s: Unexpected broken word: %q", k, word) + } + } + } +} + +func TestMaxWidthWriter(t *testing.T) { + testcases := map[string]struct { + input string + maxWidth uint + }{ + "max 10": {input: test, maxWidth: 10}, + "max 80": {input: test, maxWidth: 80}, + "max 120": {input: test, maxWidth: 120}, + "max 5000": {input: test, maxWidth: 5000}, + } + for k, tc := range testcases { + b := bytes.NewBufferString("") + w := NewMaxWidthWriter(b, tc.maxWidth) + _, err := w.Write([]byte(tc.input)) + if err != nil { + t.Errorf("%s: Unexpected error: %v", k, err) + } + result := b.String() + if !strings.Contains(result, "Iam") { + t.Errorf("%s: Expected to contain \"Iam\"", k) + } + if len(result) < len(tc.input) { + t.Errorf( + "%s: Unexpectedly short string, got %d wanted at least %d chars: %q", + k, + len(result), + len(tc.input), + result, + ) + } + lines := strings.Split(result, "\n") + for i, line := range lines { + if len(line) > int(tc.maxWidth) { + t.Errorf("%s: Every line must be at most %d chars long, got %d: %q", k, tc.maxWidth, len(line), line) + } + if i < len(lines)-1 && len(line) != int(tc.maxWidth) { + t.Errorf( + "%s: Lines except the last one are expected to be exactly %d chars long, got %d: %q", + k, + tc.maxWidth, + len(line), + line, + ) + } + } + } +} diff --git a/tools/infra/infra.go b/tools/infra/infra.go new file mode 100644 index 000000000..cc20a17c7 --- /dev/null +++ b/tools/infra/infra.go @@ -0,0 +1,40 @@ +// 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 main + +import ( + "fmt" + "log" +) + +func main() { + log.Println("Current module is still under development.") + message := ` +Current module is still under development. + +____ _____ __ __ +/ __ \ |_ _|| \/ | +| | | | _ __ ___ _ __ | | | \ / | +| | | || '_ \ / _ \| '_ \ | | | |\/| | +| |__| || |_) || __/| | | | _| |_ | | | | +\____/ | .__/ \___||_| |_||_____||_| |_| + | | + |_| + +Keep checking for updates! +` + + fmt.Println(message) +} diff --git a/tools/infra/main.go b/tools/infra/main.go deleted file mode 100644 index 55243d386..000000000 --- a/tools/infra/main.go +++ /dev/null @@ -1,26 +0,0 @@ -package main - -import ( - "fmt" - "log" -) - -func main() { - log.Println("Current module is still under development.") - message := ` -Current module is still under development. - -____ _____ __ __ -/ __ \ |_ _|| \/ | -| | | | _ __ ___ _ __ | | | \ / | -| | | || '_ \ / _ \| '_ \ | | | |\/| | -| |__| || |_) || __/| | | | _| |_ | | | | -\____/ | .__/ \___||_| |_||_____||_| |_| - | | - |_| - -Keep checking for updates! -` - - fmt.Println(message) -} diff --git a/tools/ncpu/README.md b/tools/ncpu/README.md new file mode 100644 index 000000000..7edda5328 --- /dev/null +++ b/tools/ncpu/README.md @@ -0,0 +1,47 @@ +# ncpu + +**ncpu** is a simple utility to fetch the number of CPU cores across different operating systems. + +## Introduction + +In various scenarios, especially while compiling code, it's beneficial to know the number of available CPU cores to optimize the build process. However, the command to fetch the CPU core count differs between operating systems. For example, on Linux, we use `nproc`, while on macOS, it's `sysctl -n hw.ncpu`. The `ncpu` utility provides a unified way to obtain this number, regardless of the platform. + +## Usage + +To retrieve the number of CPU cores, simply use the `ncpu` command: + +```bash +$ ncpu +``` + +This will return an integer representing the number of available CPU cores. + +### Example: + +Let's say you're compiling a project using `make`. To utilize all the CPU cores for the compilation process, you can use: + +```bash +$ make -j $(ncpu) build # or any other build command +``` + +The above command will ensure the build process takes advantage of all the available CPU cores, thereby potentially speeding up the compilation. + +## Why use `ncpu`? + +- **Cross-platform compatibility**: No need to remember or detect which OS-specific command to use. Just use `ncpu`! + +- **Ease of use**: A simple and intuitive command that's easy to incorporate into scripts or command-line operations. + +- **Consistency**: Ensures consistent behavior and output across different systems and environments. + +## Installation + +(Include installation steps here, e.g., how to clone the repo, build the tool, or install via package manager.) + +## Contributing + +If you have any suggestions, bug reports, or wish to contribute to the development of `ncpu`, please refer to our contribution guidelines (link to guidelines). + +## License + +`ncpu` is released under the [LICENSE_NAME](LINK_TO_LICENSE). Please refer to the license file for more details. \ No newline at end of file diff --git a/tools/ncpu/main.go b/tools/ncpu/main.go deleted file mode 100644 index b55852554..000000000 --- a/tools/ncpu/main.go +++ /dev/null @@ -1,13 +0,0 @@ -package main - -import ( - "fmt" - "runtime" - - "go.uber.org/automaxprocs/maxprocs" -) - -func main() { - maxprocs.Set() - fmt.Print(runtime.GOMAXPROCS(0)) -} diff --git a/tools/ncpu/ncpu.go b/tools/ncpu/ncpu.go new file mode 100644 index 000000000..7ca3dff5e --- /dev/null +++ b/tools/ncpu/ncpu.go @@ -0,0 +1,27 @@ +// 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 main + +import ( + "fmt" + "runtime" + + "go.uber.org/automaxprocs/maxprocs" +) + +func main() { + maxprocs.Set() + fmt.Print(runtime.GOMAXPROCS(0)) +} diff --git a/tools/ncpu/ncpu_test.go b/tools/ncpu/ncpu_test.go new file mode 100644 index 000000000..f24203226 --- /dev/null +++ b/tools/ncpu/ncpu_test.go @@ -0,0 +1,35 @@ +// 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 main + +import "testing" + +func Test_main(t *testing.T) { + tests := []struct { + name string + }{ + { + name: "Test_main", + }, + { + name: "Test_main2", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + main() + }) + } +} diff --git a/tools/yamlfmt/OWNERS b/tools/yamlfmt/OWNERS new file mode 100644 index 000000000..b7a5428e7 --- /dev/null +++ b/tools/yamlfmt/OWNERS @@ -0,0 +1,10 @@ +# See the OWNERS docs at https://go.k8s.io/owners + +reviewers: + - cubxxw + - kubbot +approvers: + - cubxxw +labels: + - sig/testing + - sig/contributor-experience \ No newline at end of file diff --git a/tools/yamlfmt/go.mod b/tools/yamlfmt/go.mod new file mode 100644 index 000000000..a6acf38a1 --- /dev/null +++ b/tools/yamlfmt/go.mod @@ -0,0 +1,8 @@ +module github.com/OpenIMSDK/Open-IM-Server/tools/yamlfmt + +go 1.20 + +require ( + github.com/likexian/gokit v0.25.13 + gopkg.in/yaml.v3 v3.0.1 +) diff --git a/tools/yamlfmt/go.sum b/tools/yamlfmt/go.sum new file mode 100644 index 000000000..0cf090cc8 --- /dev/null +++ b/tools/yamlfmt/go.sum @@ -0,0 +1,6 @@ +github.com/likexian/gokit v0.25.13 h1:p2Uw3+6fGG53CwdU2Dz0T6bOycdb2+bAFAa3ymwWVkM= +github.com/likexian/gokit v0.25.13/go.mod h1:qQhEWFBEfqLCO3/vOEo2EDKd+EycekVtUK4tex+l2H4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/tools/yamlfmt/yamlfmt.go b/tools/yamlfmt/yamlfmt.go new file mode 100644 index 000000000..4bad00fca --- /dev/null +++ b/tools/yamlfmt/yamlfmt.go @@ -0,0 +1,72 @@ +// 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 plan on prow tools +package main + +import ( + "flag" + "fmt" + "io" + "os" + + "gopkg.in/yaml.v3" +) + +func main() { + // Prow OWNERs file defines the default indent as 2 spaces. + indent := flag.Int("indent", 2, "default indent") + flag.Parse() + for _, path := range flag.Args() { + sourceYaml, err := os.ReadFile(path) + if err != nil { + fmt.Fprintf(os.Stderr, "%s: %v\n", path, err) + continue + } + rootNode, err := fetchYaml(sourceYaml) + if err != nil { + fmt.Fprintf(os.Stderr, "%s: %v\n", path, err) + continue + } + writer, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + fmt.Fprintf(os.Stderr, "%s: %v\n", path, err) + continue + } + err = streamYaml(writer, indent, rootNode) + if err != nil { + fmt.Fprintf(os.Stderr, "%s: %v\n", path, err) + continue + } + } +} + +func fetchYaml(sourceYaml []byte) (*yaml.Node, error) { + rootNode := yaml.Node{} + err := yaml.Unmarshal(sourceYaml, &rootNode) + if err != nil { + return nil, err + } + return &rootNode, nil +} + +func streamYaml(writer io.Writer, indent *int, in *yaml.Node) error { + encoder := yaml.NewEncoder(writer) + encoder.SetIndent(*indent) + err := encoder.Encode(in) + if err != nil { + return err + } + return encoder.Close() +} \ No newline at end of file diff --git a/tools/yamlfmt/yamlfmt_test.go b/tools/yamlfmt/yamlfmt_test.go new file mode 100644 index 000000000..481eee2bc --- /dev/null +++ b/tools/yamlfmt/yamlfmt_test.go @@ -0,0 +1,158 @@ +// 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 main + +import ( + "bufio" + "bytes" + "reflect" + "testing" + + "github.com/likexian/gokit/assert" + "gopkg.in/yaml.v3" +) + +func Test_main(t *testing.T) { + sourceYaml := ` # See the OWNERS docs at https://go.k8s.io/owners +approvers: +- dep-approvers +- thockin # Network +- liggitt + +labels: +- sig/architecture +` + + outputYaml := `# See the OWNERS docs at https://go.k8s.io/owners +approvers: + - dep-approvers + - thockin # Network + - liggitt +labels: + - sig/architecture +` + node, _ := fetchYaml([]byte(sourceYaml)) + var output bytes.Buffer + indent := 2 + writer := bufio.NewWriter(&output) + _ = streamYaml(writer, &indent, node) + _ = writer.Flush() + assert.Equal(t, outputYaml, string(output.Bytes()), "yaml was not formatted correctly") +} + +func Test_fetchYaml(t *testing.T) { + type args struct { + sourceYaml []byte + } + tests := []struct { + name string + args args + want *yaml.Node + wantErr bool + }{ + { + name: "Valid YAML", + args: args{sourceYaml: []byte("key: value")}, + want: &yaml.Node{ + Kind: yaml.MappingNode, + Tag: "!!map", + Value: "", + Content: []*yaml.Node{ + &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: "!!str", + Value: "key", + }, + &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: "!!str", + Value: "value", + }, + }, + }, + wantErr: false, + }, + { + name: "Invalid YAML", + args: args{sourceYaml: []byte("key:")}, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := fetchYaml(tt.args.sourceYaml) + if (err != nil) != tt.wantErr { + t.Errorf("fetchYaml() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("fetchYaml() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_streamYaml(t *testing.T) { + type args struct { + indent *int + in *yaml.Node + } + defaultIndent := 2 + tests := []struct { + name string + args args + wantWriter string + wantErr bool + }{ + { + name: "Valid YAML node with default indent", + args: args{ + indent: &defaultIndent, + in: &yaml.Node{ + Kind: yaml.MappingNode, + Tag: "!!map", + Value: "", + Content: []*yaml.Node{ + &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: "!!str", + Value: "key", + }, + &yaml.Node{ + Kind: yaml.ScalarNode, + Tag: "!!str", + Value: "value", + }, + }, + }, + }, + wantWriter: "key: value\n", + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + writer := &bytes.Buffer{} + if err := streamYaml(writer, tt.args.indent, tt.args.in); (err != nil) != tt.wantErr { + t.Errorf("streamYaml() error = %v, wantErr %v", err, tt.wantErr) + return + } + if gotWriter := writer.String(); gotWriter != tt.wantWriter { + t.Errorf("streamYaml() = %v, want %v", gotWriter, tt.wantWriter) + } + }) + } +}