Merge branch 'local-dev'
# Conflicts: # agent-go/octopus-agent-dev.yaml
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"description": "",
|
||||
"directory": "~.fastRequest~collections~Root~Default Group",
|
||||
"filePath": "~.fastRequest~collections~Root~Default Group~",
|
||||
"groupId": "1",
|
||||
"id": "1",
|
||||
"name": "Default Group",
|
||||
"type": 1
|
||||
}
|
||||
9
.fastRequest/collections/Root/directory.json
Normal file
9
.fastRequest/collections/Root/directory.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"description": "",
|
||||
"directory": "~.fastRequest~collections~Root",
|
||||
"filePath": "~.fastRequest~collections~Root~",
|
||||
"groupId": "-1",
|
||||
"id": "0",
|
||||
"name": "Root",
|
||||
"type": 1
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"description": "",
|
||||
"directory": "~.fastRequest~collections~Root~server~ExecutionController",
|
||||
"filePath": "~.fastRequest~collections~Root~server~ExecutionController~",
|
||||
"id": "20230222093108443",
|
||||
"name": "ExecutionController",
|
||||
"type": 3
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"activeGroup": "Default",
|
||||
"apiParamGroup": {},
|
||||
"childList": [],
|
||||
"description": "",
|
||||
"directory": "~.fastRequest~collections~Root~server~ExecutionController",
|
||||
"domain": "http://localhost:9999",
|
||||
"enableEnv": "local",
|
||||
"enableProject": "ProjectOctopus",
|
||||
"filePath": "~.fastRequest~collections~Root~server~ExecutionController~patchCommandToAgentAll.rapi",
|
||||
"headerList": [],
|
||||
"id": "api_io.wdd.rpc.controller.ExecutionController.patchCommandToAgentAll",
|
||||
"name": "[命令]- 发送命令至所有的主机",
|
||||
"paramGroup": {
|
||||
"bodyKeyValueListJson": "",
|
||||
"className": "io.wdd.rpc.controller.ExecutionController",
|
||||
"jsonDocument": "",
|
||||
"method": "patchCommandToAgentAll",
|
||||
"methodDescription": "[命令]- 发送命令至所有的主机",
|
||||
"methodType": "POST",
|
||||
"multipartKeyValueListJson": "[]",
|
||||
"originUrl": "/octopus/server/executor/command/all",
|
||||
"pathParamsKeyValueListJson": "[]",
|
||||
"postScript": "",
|
||||
"postType": "json",
|
||||
"preScript": "",
|
||||
"returnDocument": "{\n\t\"code\":\"No comment,Type =Number\",\n\t\"msg\":\"No comment,Type =String\",\n\t\"data\":{}\n}",
|
||||
"tempId": "",
|
||||
"url": "/octopus/server/executor/command/all",
|
||||
"urlEncodedKeyValueListJson": "[{\"comment\":\"命令行\",\"customFlag\":2,\"enabled\":true,\"key\":\"commandList\",\"type\":\"String\",\"value\":\"apt-get,update\"},{\"comment\":\"\",\"customFlag\":2,\"enabled\":true,\"key\":\"type\",\"type\":\"String\",\"value\":\"\"}]",
|
||||
"urlEncodedKeyValueListText": "commandList=apt-get,update\n&type=",
|
||||
"urlParamsKeyValueListJson": "[]",
|
||||
"urlParamsKeyValueListText": ""
|
||||
},
|
||||
"tempId": "id_io.wdd.rpc.controller.ExecutionController.patchCommandToAgentAll",
|
||||
"type": 2
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"activeGroup": "Default",
|
||||
"apiParamGroup": {},
|
||||
"childList": [],
|
||||
"description": "",
|
||||
"directory": "~.fastRequest~collections~Root~server~SchedulerController",
|
||||
"domain": "http://localhost:9999",
|
||||
"enableEnv": "local",
|
||||
"enableProject": "ProjectOctopus",
|
||||
"filePath": "~.fastRequest~collections~Root~server~SchedulerController~createScriptScheduler.rapi",
|
||||
"headerList": [],
|
||||
"id": "api_io.wdd.rpc.controller.SchedulerController.createScriptScheduler",
|
||||
"name": "新增一个定时脚本任务",
|
||||
"paramGroup": {
|
||||
"bodyKeyValueListJson": "{\n \"schedulerUuid\": \"\",\n \"name\": \"测试任务\",\n \"cronExpress\": \"30 */30 * * * ? *\",\n \"description\": \"这是注释内容\",\n \"scriptContent\": \"echo yes \\napt-get update \\necho no \\napt-get install nginx -y\",\n \"targetMachine\": \"Chengdu-amd64-98-98066f\",\n \"lastExecutionId\": null,\n \"lastExecutionResultKey\": \"\",\n \"lastExecutionStatus\": null ,\n \"createTime\": \"\",\n \"updateTime\": \"\",\n \"nextScheduleTime\": \"\",\n \"lastScheduleTime\": \"\"\n}",
|
||||
"className": "io.wdd.rpc.controller.SchedulerController",
|
||||
"jsonDocument": "{\n \"schedulerUuid\": \"No comment,Value =schedulerUuid_9dr3w\",\n \"name\": \"No comment,Value =name_ucmeh\",\n \"cronExpress\": \"No comment,Value =cronExpress_qbwqm\",\n \"description\": \"No comment,Value =description_drj0c\",\n \"scriptContent\": \"脚本任务的内容\",\n \"targetMachine\": \"执行目标机器agent_topic_name列表,使用, 分隔\",\n \"lastExecutionId\": \"与 execution_log表的主键对应,方便查询执行日志\",\n \"lastExecutionResultKey\": \"与 execution_log表的 result_key 对应,方便查询执行日志\",\n \"lastExecutionStatus\": \"任务上次执行状态\",\n \"createTime\": \"定时脚本任务创建时间\",\n \"updateTime\": \"上次更新时间\",\n \"nextScheduleTime\": \"任务下次计划执行时间\",\n \"lastScheduleTime\": \"任务上次计划执行时间\"\n}",
|
||||
"method": "createScriptScheduler",
|
||||
"methodDescription": "新增一个定时脚本任务",
|
||||
"methodType": "POST",
|
||||
"multipartKeyValueListJson": "[]",
|
||||
"originUrl": "/octopus/server/scheduler/script/create",
|
||||
"pathParamsKeyValueListJson": "[]",
|
||||
"postScript": "",
|
||||
"postType": "json",
|
||||
"preScript": "",
|
||||
"returnDocument": "{\n\t\"code\":\"No comment,Type =Number\",\n\t\"msg\":\"No comment,Type =String\",\n\t\"data\":{}\n}",
|
||||
"tempId": "",
|
||||
"url": "/octopus/server/scheduler/script/create",
|
||||
"urlEncodedKeyValueListJson": "[]",
|
||||
"urlEncodedKeyValueListText": "",
|
||||
"urlParamsKeyValueListJson": "[]",
|
||||
"urlParamsKeyValueListText": ""
|
||||
},
|
||||
"tempId": "id_io.wdd.rpc.controller.SchedulerController.createScriptScheduler",
|
||||
"type": 2
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"description": "",
|
||||
"directory": "~.fastRequest~collections~Root~server~SchedulerController",
|
||||
"filePath": "~.fastRequest~collections~Root~server~SchedulerController~",
|
||||
"id": "20230116173428298",
|
||||
"name": "SchedulerController",
|
||||
"type": 3
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"activeGroup": "Default",
|
||||
"apiParamGroup": {},
|
||||
"childList": [],
|
||||
"description": "",
|
||||
"directory": "~.fastRequest~collections~Root~server~SchedulerController",
|
||||
"domain": "http://localhost:9999",
|
||||
"enableEnv": "local",
|
||||
"enableProject": "ProjectOctopus",
|
||||
"filePath": "~.fastRequest~collections~Root~server~SchedulerController~queryAllQuartzJob.rapi",
|
||||
"headerList": [],
|
||||
"id": "api_io.wdd.rpc.controller.SchedulerController.queryAllQuartzJob",
|
||||
"name": "查询所有job",
|
||||
"paramGroup": {
|
||||
"bodyKeyValueListJson": "",
|
||||
"className": "io.wdd.rpc.controller.SchedulerController",
|
||||
"jsonDocument": "",
|
||||
"method": "queryAllQuartzJob",
|
||||
"methodDescription": "查询所有job",
|
||||
"methodType": "GET",
|
||||
"multipartKeyValueListJson": "[]",
|
||||
"originUrl": "/octopus/server/scheduler/queryAllJob",
|
||||
"pathParamsKeyValueListJson": "[]",
|
||||
"postScript": "",
|
||||
"postType": "json",
|
||||
"preScript": "",
|
||||
"returnDocument": "{\n\t\"code\":\"No comment,Type =Number\",\n\t\"msg\":\"No comment,Type =String\",\n\t\"data\":{}\n}",
|
||||
"tempId": "",
|
||||
"url": "/octopus/server/scheduler/queryAllJob",
|
||||
"urlEncodedKeyValueListJson": "[]",
|
||||
"urlEncodedKeyValueListText": "",
|
||||
"urlParamsKeyValueListJson": "[]",
|
||||
"urlParamsKeyValueListText": ""
|
||||
},
|
||||
"tempId": "id_io.wdd.rpc.controller.SchedulerController.queryAllQuartzJob",
|
||||
"type": 2
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"activeGroup": "Default",
|
||||
"apiParamGroup": {},
|
||||
"childList": [],
|
||||
"description": "",
|
||||
"directory": "~.fastRequest~collections~Root~server~SchedulerController",
|
||||
"domain": "http://localhost:9999",
|
||||
"enableEnv": "local",
|
||||
"enableProject": "ProjectOctopus",
|
||||
"filePath": "~.fastRequest~collections~Root~server~SchedulerController~queryAllTriggers.rapi",
|
||||
"headerList": [],
|
||||
"id": "api_io.wdd.rpc.controller.SchedulerController.queryAllTriggers",
|
||||
"name": "查询所有的触发器Trigger",
|
||||
"paramGroup": {
|
||||
"bodyKeyValueListJson": "",
|
||||
"className": "io.wdd.rpc.controller.SchedulerController",
|
||||
"jsonDocument": "",
|
||||
"method": "queryAllTriggers",
|
||||
"methodDescription": "查询所有的触发器Trigger",
|
||||
"methodType": "GET",
|
||||
"multipartKeyValueListJson": "[]",
|
||||
"originUrl": "/octopus/server/scheduler/allTriggers",
|
||||
"pathParamsKeyValueListJson": "[]",
|
||||
"postScript": "",
|
||||
"postType": "json",
|
||||
"preScript": "",
|
||||
"returnDocument": "{\n\t\"code\":\"No comment,Type =Number\",\n\t\"msg\":\"No comment,Type =String\",\n\t\"data\":{}\n}",
|
||||
"tempId": "",
|
||||
"url": "/octopus/server/scheduler/allTriggers",
|
||||
"urlEncodedKeyValueListJson": "[]",
|
||||
"urlEncodedKeyValueListText": "",
|
||||
"urlParamsKeyValueListJson": "[]",
|
||||
"urlParamsKeyValueListText": ""
|
||||
},
|
||||
"tempId": "id_io.wdd.rpc.controller.SchedulerController.queryAllTriggers",
|
||||
"type": 2
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"activeGroup": "Default",
|
||||
"apiParamGroup": {},
|
||||
"childList": [],
|
||||
"description": "",
|
||||
"directory": "~.fastRequest~collections~Root~server~SchedulerController",
|
||||
"domain": "http://localhost:9999",
|
||||
"enableEnv": "local",
|
||||
"enableProject": "ProjectOctopus",
|
||||
"filePath": "~.fastRequest~collections~Root~server~SchedulerController~queryRunQuartzJob.rapi",
|
||||
"headerList": [],
|
||||
"id": "api_io.wdd.rpc.controller.SchedulerController.queryRunQuartzJob",
|
||||
"name": "查询所有运行job",
|
||||
"paramGroup": {
|
||||
"bodyKeyValueListJson": "",
|
||||
"className": "io.wdd.rpc.controller.SchedulerController",
|
||||
"jsonDocument": "",
|
||||
"method": "queryRunQuartzJob",
|
||||
"methodDescription": "查询所有运行job",
|
||||
"methodType": "POST",
|
||||
"multipartKeyValueListJson": "[]",
|
||||
"originUrl": "/octopus/server/scheduler/queryRunJob",
|
||||
"pathParamsKeyValueListJson": "[]",
|
||||
"postScript": "",
|
||||
"postType": "json",
|
||||
"preScript": "",
|
||||
"returnDocument": "{\n\t\"code\":\"No comment,Type =Number\",\n\t\"msg\":\"No comment,Type =String\",\n\t\"data\":{}\n}",
|
||||
"tempId": "",
|
||||
"url": "/octopus/server/scheduler/queryRunJob",
|
||||
"urlEncodedKeyValueListJson": "[]",
|
||||
"urlEncodedKeyValueListText": "",
|
||||
"urlParamsKeyValueListJson": "[]",
|
||||
"urlParamsKeyValueListText": ""
|
||||
},
|
||||
"tempId": "id_io.wdd.rpc.controller.SchedulerController.queryRunQuartzJob",
|
||||
"type": 2
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"activeGroup": "Default",
|
||||
"apiParamGroup": {},
|
||||
"childList": [],
|
||||
"description": "",
|
||||
"directory": "~.fastRequest~collections~Root~server~StatusController",
|
||||
"domain": "http://localhost:9999",
|
||||
"enableEnv": "local",
|
||||
"enableProject": "ProjectOctopus",
|
||||
"filePath": "~.fastRequest~collections~Root~server~StatusController~GetHealthyStatusAgentList.rapi",
|
||||
"headerList": [],
|
||||
"id": "api_io.wdd.rpc.controller.StatusController.GetHealthyStatusAgentList",
|
||||
"name": "[ 状态-Agent ] Map",
|
||||
"paramGroup": {
|
||||
"bodyKeyValueListJson": "",
|
||||
"className": "io.wdd.rpc.controller.StatusController",
|
||||
"jsonDocument": "",
|
||||
"method": "GetHealthyStatusAgentList",
|
||||
"methodDescription": "[ 状态-Agent ] Map",
|
||||
"methodType": "GET",
|
||||
"multipartKeyValueListJson": "[]",
|
||||
"originUrl": "/octopus/server/status/status/agent",
|
||||
"pathParamsKeyValueListJson": "[]",
|
||||
"postScript": "",
|
||||
"postType": "json",
|
||||
"preScript": "",
|
||||
"returnDocument": "{\n\t\"code\":\"No comment,Type =Number\",\n\t\"msg\":\"No comment,Type =String\",\n\t\"data\":{}\n}",
|
||||
"tempId": "",
|
||||
"url": "/octopus/server/status/status/agent",
|
||||
"urlEncodedKeyValueListJson": "[]",
|
||||
"urlEncodedKeyValueListText": "",
|
||||
"urlParamsKeyValueListJson": "[]",
|
||||
"urlParamsKeyValueListText": ""
|
||||
},
|
||||
"tempId": "id_io.wdd.rpc.controller.StatusController.GetHealthyStatusAgentList",
|
||||
"type": 2
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"activeGroup": "Default",
|
||||
"apiParamGroup": {},
|
||||
"childList": [],
|
||||
"description": "",
|
||||
"directory": "~.fastRequest~collections~Root~server~StatusController",
|
||||
"domain": "http://localhost:9999",
|
||||
"enableEnv": "local",
|
||||
"enableProject": "ProjectOctopus",
|
||||
"filePath": "~.fastRequest~collections~Root~server~StatusController~ManualUpdateAgentStatus.rapi",
|
||||
"headerList": [],
|
||||
"id": "api_io.wdd.rpc.controller.StatusController.ManualUpdateAgentStatus",
|
||||
"name": "手动更新Agent的状态",
|
||||
"paramGroup": {
|
||||
"bodyKeyValueListJson": "",
|
||||
"className": "io.wdd.rpc.controller.StatusController",
|
||||
"jsonDocument": "",
|
||||
"method": "ManualUpdateAgentStatus",
|
||||
"methodDescription": "手动更新Agent的状态",
|
||||
"methodType": "POST",
|
||||
"multipartKeyValueListJson": "[]",
|
||||
"originUrl": "/octopus/server/status/agent/status/update",
|
||||
"pathParamsKeyValueListJson": "[]",
|
||||
"postScript": "",
|
||||
"postType": "json",
|
||||
"preScript": "",
|
||||
"returnDocument": "{\n\t\"code\":\"No comment,Type =Number\",\n\t\"msg\":\"No comment,Type =String\",\n\t\"data\":{}\n}",
|
||||
"tempId": "",
|
||||
"url": "/octopus/server/status/agent/status/update",
|
||||
"urlEncodedKeyValueListJson": "[]",
|
||||
"urlEncodedKeyValueListText": "",
|
||||
"urlParamsKeyValueListJson": "[]",
|
||||
"urlParamsKeyValueListText": ""
|
||||
},
|
||||
"tempId": "id_io.wdd.rpc.controller.StatusController.ManualUpdateAgentStatus",
|
||||
"type": 2
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"description": "",
|
||||
"directory": "~.fastRequest~collections~Root~server~StatusController",
|
||||
"filePath": "~.fastRequest~collections~Root~server~StatusController~",
|
||||
"id": "20230222092955736",
|
||||
"name": "StatusController",
|
||||
"type": 3
|
||||
}
|
||||
8
.fastRequest/collections/Root/server/directory.json
Normal file
8
.fastRequest/collections/Root/server/directory.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"description": "",
|
||||
"directory": "~.fastRequest~collections~Root~server",
|
||||
"filePath": "~.fastRequest~collections~Root~server~",
|
||||
"id": "20221230113234995",
|
||||
"name": "server",
|
||||
"type": 4
|
||||
}
|
||||
37
.fastRequest/config/fastRequestCurrentProjectConfig.json
Normal file
37
.fastRequest/config/fastRequestCurrentProjectConfig.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"dataList": [
|
||||
{
|
||||
"hostGroup": [
|
||||
{
|
||||
"env": "local",
|
||||
"url": "localhost:9090"
|
||||
}
|
||||
],
|
||||
"name": "OctpusGO"
|
||||
}
|
||||
],
|
||||
"envList": [
|
||||
"local"
|
||||
],
|
||||
"headerList": [],
|
||||
"postScript": "",
|
||||
"preScript": "",
|
||||
"projectList": [
|
||||
"OctpusGO"
|
||||
],
|
||||
"syncModel": {
|
||||
"branch": "master",
|
||||
"domain": "https://github.com",
|
||||
"enabled": false,
|
||||
"namingPolicy": "byDoc",
|
||||
"owner": "",
|
||||
"repo": "",
|
||||
"repoUrl": "",
|
||||
"syncAfterRun": false,
|
||||
"token": "",
|
||||
"type": "github"
|
||||
},
|
||||
"urlEncodedKeyValueList": [],
|
||||
"urlParamsKeyValueList": [],
|
||||
"urlSuffix": ""
|
||||
}
|
||||
2
.github/workflows/build-push-docker.yml
vendored
2
.github/workflows/build-push-docker.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'temurin'
|
||||
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
||||
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml-back
|
||||
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||
cache: maven
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Agent-Dev-LapPro-Ubuntu" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot">
|
||||
<option name="ACTIVE_PROFILES" value="dev" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="11" />
|
||||
<option name="DEBUG_MODE" value="true" />
|
||||
<envs>
|
||||
<env name="agentVersion" value="2023-02-13" />
|
||||
<env name="archInfo" value=""x86_64 (64 Bit)"" />
|
||||
<env name="cpuBrand" value=""Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz"" />
|
||||
<env name="cpuCore" value=""8 @ 4299.998 MHz"" />
|
||||
<env name="diskTotal" value=""914.9 GB"" />
|
||||
<env name="diskUsage" value=""12.3 GB"" />
|
||||
<env name="ioSpeed" value=""259 MB/s"" />
|
||||
<env name="location" value=""Chengdu Sichuan CN"" />
|
||||
<env name="machineId" value=""ubuntu-lap-pro"" />
|
||||
<env name="managePort" value=""22"" />
|
||||
<env name="memoryTotal" value=""7.6 GB"" />
|
||||
<env name="osInfo" value=""Ubuntu 20.04.5 LTS"" />
|
||||
<env name="osKernelInfo" value=""5.4.0-135-generic"" />
|
||||
<env name="provider" value=""AS139080 The Internet Data Center of Sichuan Mobile Communication Company Limited"" />
|
||||
<env name="server.port" value="8001" />
|
||||
<env name="serverIpInV4" value="""" />
|
||||
<env name="serverIpInV6" value="""" />
|
||||
<env name="serverIpPbV4" value=""183.220.149.17"" />
|
||||
<env name="serverIpPbV6" value="""" />
|
||||
<env name="serverName" value=""Chengdu-amd64-71"" />
|
||||
<env name="tcpControl" value=""cubic"" />
|
||||
<env name="virtualization" value=""Dedicated"" />
|
||||
</envs>
|
||||
<option name="HIDE_BANNER" value="true" />
|
||||
<module name="agent" />
|
||||
<option name="PASS_PARENT_ENVS" value="false" />
|
||||
<projectPathOnTarget name="projectPathOnTarget" value="$PROJECT_DIR$" />
|
||||
<option name="SPRING_BOOT_MAIN_CLASS" value="io.wdd.agent.AgentApplication" />
|
||||
<option name="VM_PARAMETERS" value="-Dserver.port=8001 -Dfile.encoding=utf-8 -Ddebug=true -Dlogging.level.io.wdd.agent=debug -Dspring.profiles.active=dev -Dspring.cloud.nacos.config.group=dev -Dspring.cloud.nacos.config.extension-configs[0].dataId=common-dev.yaml -Dspring.cloud.nacos.config.extension-configs[0].group=dev" />
|
||||
<method v="2">
|
||||
<option name="ToolBeforeRunTask" enabled="true" actionId="Tool_External Tools_git pull code" />
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,36 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Agent-dev-1" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" activateToolWindowBeforeRun="false">
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="11" />
|
||||
<envs>
|
||||
<env name="agentVersion" value="2023-02-13" />
|
||||
<env name="archInfo" value=""x86_64 (64 Bit)"" />
|
||||
<env name="cpuBrand" value=""Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz"" />
|
||||
<env name="cpuCore" value=""12 @ 4299.998 MHz"" />
|
||||
<env name="diskTotal" value=""914.9 GB"" />
|
||||
<env name="diskUsage" value=""12.3 GB"" />
|
||||
<env name="ioSpeed" value=""259 MB/s"" />
|
||||
<env name="location" value=""Chengdu Sichuan CN"" />
|
||||
<env name="machineId" value=""remote-dev-19"" />
|
||||
<env name="managePort" value=""22"" />
|
||||
<env name="memoryTotal" value=""7.6 GB"" />
|
||||
<env name="osInfo" value=""Ubuntu 20.04.5 LTS"" />
|
||||
<env name="osKernelInfo" value=""5.4.0-135-generic"" />
|
||||
<env name="provider" value=""AS139080 The Internet Data Center of Sichuan Mobile Communication Company Limited"" />
|
||||
<env name="serverIpInV4" value="""" />
|
||||
<env name="serverIpInV6" value="""" />
|
||||
<env name="serverIpPbV4" value=""183.220.149.17"" />
|
||||
<env name="serverIpPbV6" value="""" />
|
||||
<env name="serverName" value=""Chengdu-amd64-77"" />
|
||||
<env name="tcpControl" value=""cubic"" />
|
||||
<env name="virtualization" value=""Dedicated"" />
|
||||
<env name="server.port" value="8001" />
|
||||
</envs>
|
||||
<module name="agent" />
|
||||
<target name="UbuntuStation" />
|
||||
<option name="SPRING_BOOT_MAIN_CLASS" value="io.wdd.agent.AgentApplication" />
|
||||
<option name="VM_PARAMETERS" value="-Dserver.port=8001 -Dfile.encoding=utf-8 -Ddebug=true -Dlogging.level.io.wdd.agent=debug -Dspring.profiles.active=dev -Dspring.cloud.nacos.config.group=dev -Dspring.cloud.nacos.config.extension-configs[0].dataId=common-dev.yaml -Dspring.cloud.nacos.config.extension-configs[0].group=dev" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,37 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Agent-dev-oracle-s5" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot">
|
||||
<option name="ALTERNATIVE_JRE_PATH" value="11" />
|
||||
<envs>
|
||||
<env name="agentVersion" value="2023-02-13" />
|
||||
<env name="archInfo" value=""x86_64 (64 Bit)"" />
|
||||
<env name="cpuBrand" value="Oracle Armpre A1" />
|
||||
<env name="cpuCore" value="4 @2400MHz" />
|
||||
<env name="diskTotal" value="100GB" />
|
||||
<env name="diskUsage" value=""12.3 GB"" />
|
||||
<env name="ioSpeed" value=""259 MB/s"" />
|
||||
<env name="location" value="Seoul Seoul KR" />
|
||||
<env name="machineId" value="oracles5dsaasdadas" />
|
||||
<env name="managePort" value="22333" />
|
||||
<env name="memoryTotal" value=""7.6 GB"" />
|
||||
<env name="osInfo" value=""Ubuntu 20.04.5 LTS"" />
|
||||
<env name="osKernelInfo" value=""5.4.0-135-generic"" />
|
||||
<env name="provider" value=""AS139080 The Internet Data Center of Sichuan Mobile Communication Company Limited"" />
|
||||
<env name="server.port" value="8001" />
|
||||
<env name="serverIpInV4" value="""" />
|
||||
<env name="serverIpInV6" value="""" />
|
||||
<env name="serverIpPbV4" value="146.56.159.175" />
|
||||
<env name="serverIpPbV6" value="""" />
|
||||
<env name="serverName" value="Seoul-arm64-02" />
|
||||
<env name="tcpControl" value="bbr" />
|
||||
<env name="virtualization" value=""Dedicated"" />
|
||||
</envs>
|
||||
<option name="HIDE_BANNER" value="true" />
|
||||
<module name="agent" />
|
||||
<option name="SPRING_BOOT_MAIN_CLASS" value="io.wdd.agent.AgentApplication" />
|
||||
<option name="VM_PARAMETERS" value="-Dserver.port=8001 -Dfile.encoding=utf-8 -Ddebug=true -Dlogging.level.io.wdd.agent=debug -Dspring.profiles.active=dev -Dspring.cloud.nacos.config.group=dev -Dspring.cloud.nacos.config.extension-configs[0].dataId=common-dev.yaml -Dspring.cloud.nacos.config.extension-configs[0].group=dev" />
|
||||
<method v="2">
|
||||
<option name="ToolBeforeRunTask" enabled="true" actionId="Tool_External Tools_git pull" />
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,32 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="RunServerToRemote" type="docker-deploy" factoryName="dockerfile"
|
||||
server-name="Oracle-Seoul-0">
|
||||
<deployment type="dockerfile">
|
||||
<settings>
|
||||
<option name="imageTag" value="remote-idea"/>
|
||||
<option name="containerName" value="octopus-server-idea"/>
|
||||
<option name="portBindings">
|
||||
<list>
|
||||
<DockerPortBindingImpl>
|
||||
<option name="containerPort" value="9999"/>
|
||||
<option name="hostPort" value="9999"/>
|
||||
</DockerPortBindingImpl>
|
||||
</list>
|
||||
</option>
|
||||
<option name="sourceFilePath" value="server/Dockerfile-shanghai-remote-idea"/>
|
||||
<option name="volumeBindings">
|
||||
<list>
|
||||
<DockerVolumeBindingImpl>
|
||||
<option name="containerPath" value="/octopus-server"/>
|
||||
<option name="hostPath" value="/octopus-server"/>
|
||||
</DockerVolumeBindingImpl>
|
||||
</list>
|
||||
</option>
|
||||
</settings>
|
||||
</deployment>
|
||||
<method v="2">
|
||||
<option name="RunConfigurationTask" enabled="true" run_configuration_name="SkipTest-Package"
|
||||
run_configuration_type="MavenRunConfiguration"/>
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,16 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Server-dev" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" activateToolWindowBeforeRun="false">
|
||||
<option name="DEBUG_MODE" value="true"/>
|
||||
<option name="HIDE_BANNER" value="true" />
|
||||
<module name="server" />
|
||||
<selectedOptions>
|
||||
<option name="spring.boot.profiles" visible="false" />
|
||||
</selectedOptions>
|
||||
<option name="SPRING_BOOT_MAIN_CLASS" value="io.wdd.ServerApplication" />
|
||||
<option name="VM_PARAMETERS"
|
||||
value="-Ddebug=true -Dlogging.level.io.wdd.server=debug -Dfile.encoding=utf-8 -Dspring.profiles.active=dev -Dspring.cloud.nacos.config.group=dev -Dspring.cloud.nacos.config.extension-configs[0].dataId=common-dev.yaml -Dspring.cloud.nacos.config.extension-configs[0].group=dev"/>
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Server-k3s" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot">
|
||||
<module name="server" />
|
||||
<selectedOptions>
|
||||
<option name="spring.boot.profiles" visible="false" />
|
||||
</selectedOptions>
|
||||
<option name="SPRING_BOOT_MAIN_CLASS" value="io.wdd.ServerApplication" />
|
||||
<option name="VM_PARAMETERS" value="-Dfile.encoding=utf-8 -Dspring.profiles.active=k3s -Dspring.cloud.nacos.config.group=k3s -Dspring.cloud.nacos.config.extension-configs[0].dataId=common-k3s.yaml -Dspring.cloud.nacos.config.extension-configs[0].group=k3s" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,31 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="SkipTest-Package" type="MavenRunConfiguration" factoryName="Maven">
|
||||
<MavenSettings>
|
||||
<option name="myGeneralSettings"/>
|
||||
<option name="myRunnerSettings"/>
|
||||
<option name="myRunnerParameters">
|
||||
<MavenRunnerParameters>
|
||||
<option name="profiles">
|
||||
<set/>
|
||||
</option>
|
||||
<option name="goals">
|
||||
<list>
|
||||
<option value="clean"/>
|
||||
<option value="-DskipTests=true"/>
|
||||
<option value="package"/>
|
||||
</list>
|
||||
</option>
|
||||
<option name="pomFileName"/>
|
||||
<option name="profilesMap">
|
||||
<map>
|
||||
<entry key="pom.xml" value="true"/>
|
||||
</map>
|
||||
</option>
|
||||
<option name="resolveToWorkspace" value="false"/>
|
||||
<option name="workingDirPath" value="$PROJECT_DIR$"/>
|
||||
</MavenRunnerParameters>
|
||||
</option>
|
||||
</MavenSettings>
|
||||
<method v="2"/>
|
||||
</configuration>
|
||||
</component>
|
||||
216
agent-go/AgentInitialization.go
Normal file
216
agent-go/AgentInitialization.go
Normal file
@@ -0,0 +1,216 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"agent-go/executor"
|
||||
"agent-go/g"
|
||||
"agent-go/rabbitmq"
|
||||
"agent-go/register"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/ioutil"
|
||||
"time"
|
||||
)
|
||||
|
||||
var omType = g.InitOmType
|
||||
var P = g.G.P
|
||||
|
||||
var AgentServerInfoCache = ®ister.AgentServerInfo{}
|
||||
|
||||
func INIT() *register.AgentServerInfo {
|
||||
|
||||
// 获取系统的环境变量
|
||||
agentServerInfo := parseAgentServerInfo()
|
||||
|
||||
agentConfig := g.G.AgentConfig
|
||||
|
||||
initToServerProp := &rabbitmq.ConnectProperty{
|
||||
ExchangeName: agentConfig.GetString("octopus.message.init_exchange"),
|
||||
QueueName: agentConfig.GetString("octopus.message.init_to_server"),
|
||||
ExchangeType: g.QueueDirect,
|
||||
TopicKey: agentConfig.GetString("octopus.message.init_to_server_key"),
|
||||
}
|
||||
|
||||
initFromServerProp := &rabbitmq.ConnectProperty{
|
||||
ExchangeName: agentConfig.GetString("octopus.message.init_exchange"),
|
||||
QueueName: agentConfig.GetString("octopus.message.init_from_server"),
|
||||
ExchangeType: g.QueueDirect,
|
||||
TopicKey: agentConfig.GetString("octopus.message.init_from_server_key"),
|
||||
}
|
||||
|
||||
// 建立RabbitMQ的连接
|
||||
initToServerQueue := &rabbitmq.RabbitQueue{
|
||||
RabbitProp: initToServerProp,
|
||||
}
|
||||
defer initToServerQueue.Close()
|
||||
|
||||
// 建立连接
|
||||
initToServerQueue.Connect()
|
||||
|
||||
// 组装OctopusMessage
|
||||
var octopusMsg *rabbitmq.OctopusMessage
|
||||
octopusMsg = octopusMsg.Build(
|
||||
omType,
|
||||
agentServerInfo,
|
||||
)
|
||||
msgBytes, err := json.Marshal(octopusMsg)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("octopus message convert to json is wrong! msg is => %v", octopusMsg))
|
||||
}
|
||||
|
||||
// 发送OM至MQ中
|
||||
P.Submit(
|
||||
func() {
|
||||
for g.G.AgentHasRegister == false {
|
||||
|
||||
log.Debug(fmt.Sprintf("Send init message to server! ==> %s", string(msgBytes)))
|
||||
|
||||
//如果agent存活 而Server不存活 那么需要持续不断的向Server中发送消息
|
||||
initToServerQueue.Send(
|
||||
msgBytes,
|
||||
)
|
||||
// 休眠
|
||||
time.Sleep(10 * time.Minute)
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// 监听初始化连接中的信息
|
||||
initFromServerQueue := &rabbitmq.RabbitQueue{
|
||||
RabbitProp: initFromServerProp,
|
||||
}
|
||||
//defer initFromServerQueue.Close()
|
||||
|
||||
// 建立连接
|
||||
initFromServerQueue.Connect()
|
||||
|
||||
// 建立运行时RabbitMQ连接
|
||||
handleInitMsgFromServer(initFromServerQueue, initToServerQueue, agentServerInfo)
|
||||
|
||||
return agentServerInfo
|
||||
}
|
||||
|
||||
// handleInitMsgFromServer 处理从Server接收的 注册信息
|
||||
func handleInitMsgFromServer(initFromServerQueue *rabbitmq.RabbitQueue, initToServerQueue *rabbitmq.RabbitQueue, agentServerInfo *register.AgentServerInfo) {
|
||||
|
||||
initOctopusMessageDeliveries := initFromServerQueue.Read(false)
|
||||
|
||||
// 2023年6月19日 修复注册信息一直没有完全消费的问题
|
||||
findRealAgentTopicName := ""
|
||||
|
||||
// 同步很多抢占注册的情况
|
||||
for delivery := range initOctopusMessageDeliveries {
|
||||
|
||||
log.Debug(fmt.Sprintf("message received from server is %s", string(delivery.Body)))
|
||||
|
||||
var initOctopusMsg *rabbitmq.OctopusMessage
|
||||
err := json.Unmarshal(delivery.Body, &initOctopusMsg)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("parse init message from server wroong, message is => %s ",
|
||||
string(delivery.Body)))
|
||||
}
|
||||
|
||||
var serverInfo register.AgentServerInfo
|
||||
|
||||
s, er := initOctopusMsg.Content.(string)
|
||||
if !er {
|
||||
log.ErrorF("convet to string error! => %v", er)
|
||||
}
|
||||
cc := json.Unmarshal([]byte(s), &serverInfo)
|
||||
if cc != nil {
|
||||
log.Error(fmt.Sprintf("parse init message from server wroong, message is => %v ", cc))
|
||||
}
|
||||
serverName := serverInfo.ServerName
|
||||
|
||||
// 处理OM信息
|
||||
if initOctopusMsg != nil && initOctopusMsg.Type == g.InitOmType && serverName == agentServerInfo.ServerName {
|
||||
// 是本机的注册回复信息
|
||||
log.InfoF("OctopusMessage INIT from server is this agent !")
|
||||
|
||||
// 手动确认信息
|
||||
delivery.Ack(false)
|
||||
|
||||
// 修改系统参数
|
||||
g.G.AgentHasRegister = true
|
||||
|
||||
// 保存真实的AgentTopicName
|
||||
findRealAgentTopicName = serverInfo.TopicName
|
||||
|
||||
// 手动关闭 注册队列的连接
|
||||
shutdownRegisterQueueConnection(initFromServerQueue, initToServerQueue)
|
||||
|
||||
} else {
|
||||
// 不是自身的 注册回复信息 -- 拒绝 2023年6月19日 此处存在错误! 会死循环Nack 导致异常
|
||||
log.Warn(fmt.Sprintf("OctopusMessage INIT from server not this agent ! => %v, ==>%s", initOctopusMsg, delivery.Body))
|
||||
delivery.Ack(false)
|
||||
|
||||
// 需要休眠等待不再获取相应的信息
|
||||
time.Sleep(5 * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
// 建立 运行时 RabbitMQ连接
|
||||
rabbitmq.BuildOMsgRuntimeConnectorQueue(findRealAgentTopicName)
|
||||
|
||||
}
|
||||
|
||||
// shutdownRegisterQueueConnection 关闭初始化连接的两个队列
|
||||
func shutdownRegisterQueueConnection(initFromServerQueue *rabbitmq.RabbitQueue, initToServerQueue *rabbitmq.RabbitQueue) {
|
||||
|
||||
initFromServerQueue.Close()
|
||||
initToServerQueue.Close()
|
||||
|
||||
log.InfoF("Pretend to Shutdown register queue connection !")
|
||||
}
|
||||
|
||||
func parseAgentServerInfo() *register.AgentServerInfo {
|
||||
|
||||
// 约定文件地址为 /etc/environment.d/octopus-agent.conf
|
||||
// 目前使用
|
||||
var agentServerInfo *register.AgentServerInfo
|
||||
//yamlFile, err := ioutil.ReadFile("C:\\Users\\wdd\\IdeaProjects\\ProjectOctopus\\agent-go\\server-env.yaml")
|
||||
yamlFile, err := ioutil.ReadFile("server-env.yaml")
|
||||
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to read YAML file: %v", err))
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(yamlFile, &agentServerInfo)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to unmarshal YAML: %v", err))
|
||||
}
|
||||
|
||||
jsonFormat, err := json.Marshal(agentServerInfo)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("agent server info convert error ! agentserverinfo is %v", agentServerInfo))
|
||||
panic(err)
|
||||
}
|
||||
log.Info(fmt.Sprintf("agent server info is %v", string(jsonFormat)))
|
||||
|
||||
// build a operator cache
|
||||
BuildAgentOsOperator(agentServerInfo)
|
||||
|
||||
return agentServerInfo
|
||||
}
|
||||
|
||||
func BuildAgentOsOperator(agentServerInfo *register.AgentServerInfo) {
|
||||
|
||||
executor.AgentOsOperatorCache = &executor.AgentOsOperator{
|
||||
InstallCommandPrefix: []string{
|
||||
"apt-get", "install", "-y",
|
||||
},
|
||||
RemoveCommandPrefix: []string{"apt", "remove", "-y"},
|
||||
CanAccessInternet: true,
|
||||
IsOsTypeUbuntu: true,
|
||||
IsAgentInnerWall: true,
|
||||
AgentArch: "amd64",
|
||||
AgentOSReleaseCode: "focal",
|
||||
AgentServerInfo: agentServerInfo,
|
||||
}
|
||||
|
||||
// debug
|
||||
marshal, _ := json.Marshal(executor.AgentOsOperatorCache)
|
||||
log.DebugF("cached agent operator is %s", marshal)
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package main
|
||||
|
||||
/*type RabbitSendWriter interface {
|
||||
|
||||
Send(conn *RabbitMQConn, connProp *ConnectProperty, message []byte)
|
||||
|
||||
Read(conn *RabbitMQConn, connProp *ConnectProperty, autoAck bool) <-chan amqp.Delivery
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -1,50 +0,0 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"agent-go/utils"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
type OctopusMessage struct {
|
||||
UUID string `json:"uuid"`
|
||||
InitTime time.Time `json:"init_time" format:"2023-03-21 16:38:30"`
|
||||
Type string `json:"type"`
|
||||
Content interface{} `json:"content"`
|
||||
Result interface{} `json:"result"`
|
||||
ACTime time.Time `json:"ac_time" format:"2023-03-21 16:38:30"`
|
||||
}
|
||||
|
||||
type ExecutionMessage struct {
|
||||
NeedResultReplay bool `json:"needResultReplay"`
|
||||
DurationTask bool `json:"durationTask,default:false"`
|
||||
Type string `json:"type"`
|
||||
SingleLineCommand []string `json:"singleLineCommand"`
|
||||
MultiLineCommand [][]string `json:"multiLineCommand"`
|
||||
PipeLineCommand [][]string `json:"pipeLineCommand"`
|
||||
ResultKey string `json:"resultKey"`
|
||||
}
|
||||
|
||||
// BuildOctopusMsg 生成OctopusMessage
|
||||
func (m *OctopusMessage) BuildOctopusMsg(omType string, content interface{}) *OctopusMessage {
|
||||
|
||||
// 当前时间
|
||||
curTimeString := utils.CurTimeString()
|
||||
|
||||
// must write to string format, otherwise it's very hard to deserialize
|
||||
|
||||
bytes, err := json.Marshal(content)
|
||||
if err != nil {
|
||||
fmt.Sprintf("OctopusMessage Build Error ! %v", err)
|
||||
}
|
||||
|
||||
return &OctopusMessage{
|
||||
UUID: curTimeString,
|
||||
InitTime: time.Now(),
|
||||
Type: omType,
|
||||
Content: string(bytes),
|
||||
Result: nil,
|
||||
ACTime: time.Time{},
|
||||
}
|
||||
}
|
||||
780
agent-go/executor/BaseFunction.go
Normal file
780
agent-go/executor/BaseFunction.go
Normal file
@@ -0,0 +1,780 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"agent-go/g"
|
||||
"agent-go/register"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type BaseFunc interface {
|
||||
Exec(baseFuncName string, funcArgs ...string) []string
|
||||
}
|
||||
|
||||
type AgentOsOperator struct {
|
||||
InstallCommandPrefix []string `json:"install_command_prefix",comment:"apt-get install or yum install"`
|
||||
|
||||
RemoveCommandPrefix []string `json:"remove_command_prefix",comment:"apt-get remove or yum remove"`
|
||||
|
||||
CanAccessInternet bool `json:"can_access_internet",comment:"是否可以访问公网"`
|
||||
|
||||
IsOsTypeUbuntu bool `json:"is_os_type_ubuntu",comment:"主机操作系统是否为ubuntu系列"`
|
||||
|
||||
IsAgentInnerWall bool `json:"is_agent_inner_wall",comment:"主机是否身处国内"`
|
||||
|
||||
AgentArch string `json:"agent_arch",comment:"主机的CPU架构,可选为amd64 arm64"`
|
||||
|
||||
AgentOSReleaseCode string `json:"agent_os_release_code",comment:"主机操作系统的发行版代号, focal之类的"`
|
||||
|
||||
AgentServerInfo *register.AgentServerInfo `json:"agent_server_info"`
|
||||
}
|
||||
|
||||
// Exec 执行基础功能函数
|
||||
func (op *AgentOsOperator) Exec(baseFuncName string, funcArgs ...string) []string {
|
||||
|
||||
var multiLineCommand [][]string
|
||||
|
||||
switch baseFuncName {
|
||||
|
||||
case "shutdownFirewall":
|
||||
multiLineCommand = op.shutdownFirewall()
|
||||
break
|
||||
case "modifyHostname":
|
||||
multiLineCommand = op.modifyHostname(funcArgs)
|
||||
break
|
||||
case "enableSwap":
|
||||
multiLineCommand = op.enableSwap()
|
||||
break
|
||||
case "disableSwap":
|
||||
multiLineCommand = op.disableSwap()
|
||||
break
|
||||
case "installDocker":
|
||||
multiLineCommand = op.installDocker(funcArgs)
|
||||
break
|
||||
case "removeDocker":
|
||||
multiLineCommand = op.removeDocker()
|
||||
break
|
||||
case "removeDockerCompose":
|
||||
multiLineCommand = op.removeDockerCompose()
|
||||
break
|
||||
case "installDockerCompose":
|
||||
multiLineCommand = op.installDockerCompose()
|
||||
break
|
||||
case "modifyDockerConfig":
|
||||
multiLineCommand = op.modifyDockerConfig(funcArgs)
|
||||
break
|
||||
case "installHelm":
|
||||
multiLineCommand = op.installHelm()
|
||||
break
|
||||
case "installHarbor":
|
||||
multiLineCommand = op.installHarbor()
|
||||
break
|
||||
case "chronyToPublicNTP":
|
||||
multiLineCommand = op.chronyToPublicNTP()
|
||||
break
|
||||
case "chronyToMaster":
|
||||
multiLineCommand = op.chronyToMaster(funcArgs)
|
||||
break
|
||||
case "installZSH":
|
||||
multiLineCommand = op.installZSH()
|
||||
break
|
||||
case "modifySshPort":
|
||||
multiLineCommand = op.modifySshPort(funcArgs)
|
||||
break
|
||||
case "openBBR":
|
||||
multiLineCommand = op.openBBR()
|
||||
break
|
||||
default:
|
||||
multiLineCommand = op.ok(funcArgs)
|
||||
|
||||
}
|
||||
|
||||
log.DebugF("multiLineCommand are => %v", multiLineCommand)
|
||||
|
||||
var result []string
|
||||
|
||||
// exec the command here
|
||||
for _, singleLineCommand := range multiLineCommand {
|
||||
result = append(result, AllOutputCommandExecutor(singleLineCommand)...)
|
||||
|
||||
// debug usage
|
||||
log.DebugF("exec result are => %v", result)
|
||||
for _, logLine := range result {
|
||||
fmt.Println(logLine)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 归一化处理
|
||||
return result
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) shutdownFirewall() [][]string {
|
||||
|
||||
shutdownFunc := [][]string{
|
||||
{"systemctl", "stop", "firewalld"},
|
||||
{"systemctl", "disable", "firewalld"},
|
||||
}
|
||||
|
||||
if !op.IsOsTypeUbuntu {
|
||||
shutdownFunc = append(shutdownFunc,
|
||||
[]string{
|
||||
"sed",
|
||||
"-i",
|
||||
"s/SELINUX=enforcing/SELINUX=disabled/g",
|
||||
"/etc/selinux/config",
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return shutdownFunc
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) modifyHostname(args []string) [][]string {
|
||||
|
||||
return [][]string{}
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) enableSwap() [][]string {
|
||||
|
||||
enableSwapFunc := [][]string{
|
||||
{
|
||||
"cp",
|
||||
"-f",
|
||||
"/etc/fstab_back",
|
||||
"/etc/fstab",
|
||||
},
|
||||
{
|
||||
"cat",
|
||||
"/etc/fstab",
|
||||
},
|
||||
}
|
||||
|
||||
return enableSwapFunc
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) disableSwap() [][]string {
|
||||
|
||||
disableSwapFunc := [][]string{
|
||||
{
|
||||
"swapoff",
|
||||
"-a",
|
||||
},
|
||||
{
|
||||
"cp",
|
||||
"-f",
|
||||
"/etc/fstab",
|
||||
"/etc/fstab_back",
|
||||
},
|
||||
{
|
||||
"sed",
|
||||
"-i",
|
||||
"/swap/d",
|
||||
"/etc/fstab",
|
||||
},
|
||||
}
|
||||
|
||||
return disableSwapFunc
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) removeDocker() [][]string {
|
||||
|
||||
removeDockerLine := append(op.RemoveCommandPrefix, []string{
|
||||
"docker-ce",
|
||||
"docker.io",
|
||||
"docker-ce-cli",
|
||||
//"docker",
|
||||
//"docker-common",
|
||||
//"docker-latest",
|
||||
//"docker-latest-logrotate",
|
||||
//"docker-logrotate",
|
||||
//"docker-selinux",
|
||||
//"docker-engine-selinux",
|
||||
//"docker-engine",
|
||||
//"kubelet",
|
||||
//"kubeadm",
|
||||
//"kubectl",
|
||||
//"docker-client",
|
||||
//"docker-client-latest",
|
||||
}...)
|
||||
|
||||
removeDockerFunc := [][]string{
|
||||
removeDockerLine,
|
||||
}
|
||||
|
||||
return removeDockerFunc
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) installDocker(args []string) [][]string {
|
||||
|
||||
// remove docker all staff
|
||||
installDockerFunc := op.removeDocker()
|
||||
|
||||
if op.IsOsTypeUbuntu {
|
||||
//
|
||||
installFirstLine := append(op.InstallCommandPrefix, []string{
|
||||
"apt-transport-https",
|
||||
"ca-certificates",
|
||||
"curl",
|
||||
"gnupg-agent",
|
||||
"software-properties-common",
|
||||
}...)
|
||||
|
||||
if op.IsAgentInnerWall {
|
||||
// inner gfw
|
||||
installDockerFunc = append(installDockerFunc, [][]string{
|
||||
installFirstLine,
|
||||
{
|
||||
"curl",
|
||||
"-o",
|
||||
"/usr/share/keyrings/docker-utsc.gpg",
|
||||
"https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg",
|
||||
},
|
||||
{
|
||||
"apt-key",
|
||||
"add",
|
||||
"/usr/share/keyrings/docker-utsc.gpg",
|
||||
},
|
||||
{
|
||||
"add-apt-repository",
|
||||
"deb [arch=" + op.AgentArch + "] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu " + op.AgentOSReleaseCode + " stable",
|
||||
},
|
||||
}...)
|
||||
} else {
|
||||
// outside world
|
||||
installDockerFunc = append(installDockerFunc, [][]string{
|
||||
installFirstLine,
|
||||
{
|
||||
"curl",
|
||||
"-o",
|
||||
"/usr/share/keyrings/docker.gpg",
|
||||
"https://download.docker.com/linux/ubuntu/gpg ",
|
||||
},
|
||||
{
|
||||
"apt-key",
|
||||
"add",
|
||||
"/usr/share/keyrings/docker.gpg",
|
||||
},
|
||||
{
|
||||
"add-apt-repository",
|
||||
"deb [arch=" + op.AgentArch + "] https://download.docker.com/linux/ubuntu " + op.AgentOSReleaseCode + " stable",
|
||||
},
|
||||
}...)
|
||||
}
|
||||
|
||||
// look for specific docker-version to install
|
||||
installDockerFunc = append(installDockerFunc, []string{"apt-get", "update"})
|
||||
|
||||
var specificDockerVersion string
|
||||
// hard code here 5:20.10.10~3-0~ubuntu-focal
|
||||
if strings.HasPrefix(args[0], "19") {
|
||||
specificDockerVersion = "5:19.03.15~3-0~ubuntu-" + op.AgentOSReleaseCode
|
||||
} else {
|
||||
specificDockerVersion = "5:20.10.10~3-0~ubuntu-" + op.AgentOSReleaseCode
|
||||
}
|
||||
|
||||
installDockerFunc = append(installDockerFunc,
|
||||
append(
|
||||
op.InstallCommandPrefix,
|
||||
"docker-ce="+specificDockerVersion,
|
||||
"docker-ce-cli="+specificDockerVersion,
|
||||
"containerd.io",
|
||||
"docker-compose-plugin",
|
||||
),
|
||||
)
|
||||
|
||||
} else {
|
||||
installFirstLine := append(op.InstallCommandPrefix,
|
||||
[]string{
|
||||
"yum-utils",
|
||||
"device-mapper-persistent-data",
|
||||
"lvm2",
|
||||
}...,
|
||||
)
|
||||
|
||||
if op.IsAgentInnerWall {
|
||||
// inner gfw
|
||||
installDockerFunc = append(installDockerFunc, [][]string{
|
||||
installFirstLine,
|
||||
{
|
||||
"yum-config-manager",
|
||||
"--add-repo",
|
||||
"https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo",
|
||||
},
|
||||
{
|
||||
"sed ",
|
||||
"-i ",
|
||||
"'s/download.docker.com/mirrors.ustc.edu.cn\\/docker-ce/g' ",
|
||||
"/etc/yum.repos.d/docker-ce.repo",
|
||||
},
|
||||
{},
|
||||
}...)
|
||||
} else {
|
||||
// outside world
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return installDockerFunc
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) removeDockerCompose() [][]string {
|
||||
|
||||
installDockerComposeFunc := [][]string{
|
||||
append(
|
||||
op.RemoveCommandPrefix,
|
||||
"docker-compose",
|
||||
),
|
||||
}
|
||||
|
||||
return installDockerComposeFunc
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) installDockerCompose() [][]string {
|
||||
|
||||
installDockerComposeFunc := [][]string{
|
||||
append(
|
||||
op.InstallCommandPrefix,
|
||||
"docker-compose",
|
||||
),
|
||||
}
|
||||
|
||||
return installDockerComposeFunc
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) installHelm() [][]string {
|
||||
installHelmFunc := [][]string{
|
||||
{
|
||||
"mkdir",
|
||||
"-p",
|
||||
"/root/wdd/",
|
||||
},
|
||||
{
|
||||
"rm",
|
||||
"-rf",
|
||||
"/root/wdd/helm-v*",
|
||||
},
|
||||
{
|
||||
"rm",
|
||||
"-rf",
|
||||
"/root/wdd/linux-amd64",
|
||||
},
|
||||
{
|
||||
"wget",
|
||||
"--no-check-certificate",
|
||||
g.BaseFuncOssUrlPrefix + "helm-v3.12.1-linux-amd64.tar.gz",
|
||||
"-O",
|
||||
"/root/wdd/helm-v3.12.1-linux-amd64.tar.gz",
|
||||
},
|
||||
{
|
||||
"tar",
|
||||
"-zvxf",
|
||||
"/root/wdd/helm-v3.12.1-linux-amd64.tar.gz",
|
||||
},
|
||||
{
|
||||
"chmod",
|
||||
"+x",
|
||||
"/root/wdd/linux-amd64/helm",
|
||||
},
|
||||
{
|
||||
"mv",
|
||||
"/root/wdd/linux-amd64/helm",
|
||||
"/usr/local/bin/helm",
|
||||
},
|
||||
{
|
||||
"helm",
|
||||
"version",
|
||||
},
|
||||
}
|
||||
|
||||
/*if op.IsOsTypeUbuntu {
|
||||
installHelmFunc = [][]string{
|
||||
{
|
||||
"curl",
|
||||
"-o",
|
||||
"/usr/share/keyrings/helm.gpg",
|
||||
"https://baltocdn.com/helm/signing.asc",
|
||||
},
|
||||
{
|
||||
"apt-key",
|
||||
"add",
|
||||
"/usr/share/keyrings/helm.gpg",
|
||||
},
|
||||
{
|
||||
"add-apt-repository",
|
||||
"https://baltocdn.com/helm/stable/debian/ all main",
|
||||
},
|
||||
{
|
||||
"apt-get",
|
||||
"update",
|
||||
},
|
||||
append(op.InstallCommandPrefix, "helm"),
|
||||
}
|
||||
} else {
|
||||
log.ErrorF("Operation OS is CentOS, Helm not installed!")
|
||||
}*/
|
||||
|
||||
return installHelmFunc
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) modifyDockerConfig(args []string) [][]string {
|
||||
|
||||
harborIPAddr := args[0] + ":8033"
|
||||
|
||||
modifyDockerConfigFunc := [][]string{
|
||||
{
|
||||
"mv",
|
||||
"/etc/docker/daemon.json",
|
||||
"/etc/docker/daemon.backup.json",
|
||||
},
|
||||
{
|
||||
"wget",
|
||||
g.BaseFuncOssUrlPrefix + "daemon-config.json",
|
||||
"-O",
|
||||
"/etc/docker/daemon.json",
|
||||
},
|
||||
{
|
||||
"sed",
|
||||
"-i",
|
||||
"s/$DockerRegisterDomain/" + harborIPAddr + "/g",
|
||||
"/etc/docker/daemon.json",
|
||||
},
|
||||
{
|
||||
"systemctl",
|
||||
"restart",
|
||||
"docker.service",
|
||||
},
|
||||
}
|
||||
|
||||
return modifyDockerConfigFunc
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) installHarbor() [][]string {
|
||||
|
||||
installHarborFunc := [][]string{
|
||||
//{
|
||||
// "mkdir",
|
||||
// "-p",
|
||||
// "/root/wdd/",
|
||||
//},
|
||||
//{
|
||||
// "rm",
|
||||
// "-rf",
|
||||
// "/root/wdd/harbor-offline-installer-v2.1.0.tgz",
|
||||
//},
|
||||
//{
|
||||
// "wget",
|
||||
// "--no-check-certificate",
|
||||
// g.BaseFuncOssUrlPrefix + "harbor-offline-installer-v2.1.0.tgz",
|
||||
// "-O",
|
||||
// "/root/wdd/harbor-offline-installer-v2.1.0.tgz",
|
||||
//},
|
||||
{
|
||||
"tar",
|
||||
"-zvxf",
|
||||
"/root/wdd/harbor-offline-installer-v2.1.0.tgz",
|
||||
"-C",
|
||||
"/root/wdd/",
|
||||
},
|
||||
{
|
||||
"rm",
|
||||
"-rf",
|
||||
"/root/wdd/harbor/harbor.yml",
|
||||
},
|
||||
{
|
||||
"wget",
|
||||
"--no-check-certificate",
|
||||
g.BaseFuncOssUrlPrefix + "harbor-config-template.yml",
|
||||
"-O",
|
||||
"/root/wdd/harbor/harbor.yml",
|
||||
},
|
||||
{
|
||||
"sed",
|
||||
"-i",
|
||||
"s/$HarborHostName/" + op.AgentServerInfo.ServerIPInV4 + "/g",
|
||||
"/root/wdd/harbor/harbor.yml",
|
||||
},
|
||||
{
|
||||
"sed",
|
||||
"-i",
|
||||
"s/$HarborHostPort/8033/g",
|
||||
"/root/wdd/harbor/harbor.yml",
|
||||
},
|
||||
{
|
||||
"sed",
|
||||
"-i",
|
||||
"s/$HarborHostPort/V2ryStr@ngPss/g",
|
||||
"/root/wdd/harbor/harbor.yml",
|
||||
},
|
||||
{
|
||||
"/root/wdd/harbor/install.sh",
|
||||
"--with-chartmuseum",
|
||||
},
|
||||
}
|
||||
|
||||
return installHarborFunc
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) chronyToPublicNTP() [][]string {
|
||||
|
||||
serverIPInV4 := op.AgentServerInfo.ServerIPInV4
|
||||
internalIPCIDR := strings.Join(strings.Split(serverIPInV4, ".")[:2], ".") + ".0.0/16"
|
||||
|
||||
chronyToPublicNTPFunc := [][]string{
|
||||
append(
|
||||
op.InstallCommandPrefix,
|
||||
"chrony",
|
||||
),
|
||||
{
|
||||
"systemctl",
|
||||
"enable",
|
||||
"chronyd",
|
||||
},
|
||||
{
|
||||
"systemctl",
|
||||
"start",
|
||||
"chronyd",
|
||||
},
|
||||
}
|
||||
|
||||
var chronyFile string
|
||||
if op.IsOsTypeUbuntu {
|
||||
chronyFile = "/etc/chrony/chrony.conf"
|
||||
} else {
|
||||
chronyFile = "/etc/chrony.conf"
|
||||
}
|
||||
|
||||
chronyToPublicNTPFunc = append(chronyToPublicNTPFunc,
|
||||
[][]string{
|
||||
{
|
||||
"sed",
|
||||
"-i",
|
||||
"$ a allow " + internalIPCIDR,
|
||||
chronyFile,
|
||||
},
|
||||
{
|
||||
"sed",
|
||||
"-i",
|
||||
"s/pool ntp.ubuntu.com iburst/server ntp2.aliyun.com iburst/g",
|
||||
chronyFile,
|
||||
},
|
||||
{
|
||||
"systemctl",
|
||||
"restart",
|
||||
"chronyd",
|
||||
},
|
||||
{
|
||||
"sleep",
|
||||
"2",
|
||||
},
|
||||
{
|
||||
"chronyc",
|
||||
"-n",
|
||||
"sources",
|
||||
"-v",
|
||||
},
|
||||
{
|
||||
"chronyc",
|
||||
"tracking",
|
||||
},
|
||||
{
|
||||
"timedatectl",
|
||||
"set-timezone",
|
||||
"Asia/Shanghai",
|
||||
},
|
||||
{
|
||||
"timedatectl",
|
||||
"set-ntp",
|
||||
"true",
|
||||
},
|
||||
{
|
||||
"systemctl",
|
||||
"restart",
|
||||
"rsyslog",
|
||||
},
|
||||
}...,
|
||||
)
|
||||
|
||||
return chronyToPublicNTPFunc
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) chronyToMaster(args []string) [][]string {
|
||||
masterInnerIP := args[0]
|
||||
|
||||
chronyToMasterFunc := [][]string{
|
||||
{
|
||||
"sed",
|
||||
"-i",
|
||||
"$ a NTP=" + masterInnerIP,
|
||||
"/etc/systemd/timesyncd.conf",
|
||||
},
|
||||
{
|
||||
"systemctl",
|
||||
"daemon-reload",
|
||||
},
|
||||
{
|
||||
"systemctl",
|
||||
"restart",
|
||||
"systemd-timesyncd.service",
|
||||
},
|
||||
{
|
||||
"sleep",
|
||||
"3",
|
||||
},
|
||||
{
|
||||
"timedatectl",
|
||||
"show-timesync",
|
||||
"--all",
|
||||
},
|
||||
{
|
||||
"timedatectl",
|
||||
"status",
|
||||
},
|
||||
}
|
||||
|
||||
return chronyToMasterFunc
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) installZSH() [][]string {
|
||||
|
||||
installZSHFunc := [][]string{
|
||||
{
|
||||
"mkdir",
|
||||
"-p",
|
||||
"/root/wdd/",
|
||||
},
|
||||
append(
|
||||
op.InstallCommandPrefix,
|
||||
"zsh",
|
||||
"git",
|
||||
),
|
||||
}
|
||||
|
||||
if op.IsAgentInnerWall {
|
||||
installZSHFunc = append(
|
||||
installZSHFunc,
|
||||
[][]string{
|
||||
{
|
||||
"wget",
|
||||
"https://cdn.jsdelivr.net/gh/robbyrussell/oh-my-zsh@master/tools/install.sh",
|
||||
"-O",
|
||||
"/root/wdd/zsh-install.sh",
|
||||
},
|
||||
}...,
|
||||
)
|
||||
|
||||
} else {
|
||||
installZSHFunc = append(
|
||||
installZSHFunc,
|
||||
[][]string{
|
||||
{
|
||||
"wget",
|
||||
"https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh",
|
||||
"-O",
|
||||
"/root/wdd/zsh-install.sh",
|
||||
},
|
||||
}...,
|
||||
)
|
||||
}
|
||||
|
||||
// install
|
||||
installZSHFunc = append(
|
||||
installZSHFunc,
|
||||
[][]string{
|
||||
{
|
||||
"chmod",
|
||||
"+x",
|
||||
"/root/wdd/zsh-install.sh",
|
||||
},
|
||||
{
|
||||
"sh",
|
||||
"-c",
|
||||
"/root/wdd/zsh-install.sh",
|
||||
},
|
||||
}...,
|
||||
)
|
||||
|
||||
// modify ZSH
|
||||
if !op.IsAgentInnerWall {
|
||||
installZSHFunc = append(
|
||||
installZSHFunc,
|
||||
[][]string{
|
||||
{
|
||||
"git",
|
||||
"clone",
|
||||
"https://github.com.cnpmjs.org/zsh-users/zsh-autosuggestions",
|
||||
"~/.oh-my-zsh/plugins/zsh-autosuggestions",
|
||||
},
|
||||
{
|
||||
"git",
|
||||
"clone",
|
||||
"https://github.com.cnpmjs.org/zsh-users/zsh-syntax-highlighting.git",
|
||||
"~/.oh-my-zsh/plugins/zsh-syntax-highlighting",
|
||||
},
|
||||
{
|
||||
"wget",
|
||||
"https://b2.107421.xyz/oh-my-zsh-plugins-list.txt",
|
||||
"-O",
|
||||
"oh-my-zsh-plugins-list.txt",
|
||||
},
|
||||
{
|
||||
"wget",
|
||||
"-c",
|
||||
"-i",
|
||||
"./oh-my-zsh-plugins-list.txt",
|
||||
"-P",
|
||||
"~/.oh-my-zsh/plugins/",
|
||||
},
|
||||
{
|
||||
"sed",
|
||||
"-i",
|
||||
"s/robbyrussell/agnoster/g",
|
||||
"~/.zshrc",
|
||||
},
|
||||
{
|
||||
"sed",
|
||||
"-i",
|
||||
"s/^# DISABLE_AUTO_UPDATE=\"true\"/DISABLE_AUTO_UPDATE=\"true\"/g",
|
||||
"~/.zshrc",
|
||||
},
|
||||
{
|
||||
"sed",
|
||||
"-i",
|
||||
"s/plugins=(git)/plugins=(git zsh-autosuggestions zsh-syntax-highlighting command-not-found z themes)/g",
|
||||
"~/.zshrc",
|
||||
},
|
||||
{
|
||||
"source",
|
||||
"~/.zshrc",
|
||||
},
|
||||
{
|
||||
"chsh",
|
||||
"-s",
|
||||
"/bin/zsh",
|
||||
},
|
||||
{
|
||||
"zsh",
|
||||
},
|
||||
}...,
|
||||
)
|
||||
}
|
||||
|
||||
return installZSHFunc
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) modifySshPort(args []string) [][]string {
|
||||
|
||||
return [][]string{}
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) openBBR() [][]string {
|
||||
|
||||
return [][]string{}
|
||||
}
|
||||
|
||||
func (op *AgentOsOperator) ok(args []string) [][]string {
|
||||
log.InfoF("base function is ok , args are => " + strings.Join(args, " "))
|
||||
return [][]string{
|
||||
{"ifconfig"},
|
||||
}
|
||||
}
|
||||
60
agent-go/executor/BaseFunction_test.go
Normal file
60
agent-go/executor/BaseFunction_test.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"agent-go/register"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var agentOP = &AgentOsOperator{
|
||||
InstallCommandPrefix: []string{
|
||||
"apt-get", "install", "-y",
|
||||
},
|
||||
RemoveCommandPrefix: []string{"apt", "remove", "-y"},
|
||||
CanAccessInternet: true,
|
||||
IsOsTypeUbuntu: true,
|
||||
IsAgentInnerWall: true,
|
||||
AgentArch: "amd64",
|
||||
AgentOSReleaseCode: "focal",
|
||||
AgentServerInfo: ®ister.AgentServerInfo{
|
||||
ServerName: "",
|
||||
ServerIPPbV4: "",
|
||||
ServerIPInV4: "192.168.0.8",
|
||||
ServerIPPbV6: "",
|
||||
ServerIPInV6: "",
|
||||
Location: "",
|
||||
Provider: "",
|
||||
ManagePort: "",
|
||||
CPUCore: "",
|
||||
CPUBrand: "",
|
||||
OSInfo: "",
|
||||
OSKernelInfo: "",
|
||||
TCPControl: "",
|
||||
Virtualization: "",
|
||||
IoSpeed: "",
|
||||
MemoryTotal: "",
|
||||
DiskTotal: "",
|
||||
DiskUsage: "",
|
||||
Comment: "",
|
||||
MachineID: "",
|
||||
AgentVersion: "",
|
||||
TopicName: "",
|
||||
},
|
||||
}
|
||||
|
||||
func TestBaseFunc(t *testing.T) {
|
||||
|
||||
//agentOP.Exec("shutdownFirewall")
|
||||
//agentOP.Exec("modifyHostname")
|
||||
//agentOP.Exec("disableSwap")
|
||||
//agentOP.Exec("enableSwap")
|
||||
//agentOP.Exec("removeDocker")
|
||||
agentOP.Exec("installDocker", "20")
|
||||
//agentOP.Exec("removeDockerCompose")
|
||||
//agentOP.Exec("installDockerCompose")
|
||||
//agentOP.Exec("installHelm")
|
||||
//agentOP.Exec("installHarbor")
|
||||
//agentOP.Exec("chronyToPublicNTP")
|
||||
//agentOP.Exec("chronyToMaster", "192.168.0.8")
|
||||
//agentOP.Exec("installZSH")
|
||||
|
||||
}
|
||||
@@ -1,31 +1,56 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"agent-go/config"
|
||||
"agent-go/g"
|
||||
logger2 "agent-go/logger"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"time"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var log = g.G.LOG
|
||||
type ExecutionMessage struct {
|
||||
NeedResultReplay bool `json:"needResultReplay"`
|
||||
DurationTask bool `json:"durationTask,default:false"`
|
||||
Type string `json:"type"`
|
||||
BaseFuncContent []string `json:"baseFuncContent"`
|
||||
SingleLineCommand []string `json:"singleLineCommand"`
|
||||
MultiLineCommand [][]string `json:"multiLineCommand"`
|
||||
PipeLineCommand [][]string `json:"pipeLineCommand"`
|
||||
ResultKey string `json:"resultKey"`
|
||||
}
|
||||
|
||||
func Execute(om *config.OctopusMessage, em *config.ExecutionMessage) ([]string, error) {
|
||||
var log = logger2.Log
|
||||
|
||||
var AgentOsOperatorCache = &AgentOsOperator{}
|
||||
|
||||
func Execute(em *ExecutionMessage) ([]string, error) {
|
||||
|
||||
var resultLog []string
|
||||
var err error
|
||||
var realCommand [][]string
|
||||
|
||||
if strings.HasPrefix(em.Type, "BASE") {
|
||||
// base function
|
||||
resultLog = AgentOsOperatorCache.Exec(em.BaseFuncContent[0], em.BaseFuncContent[1:]...)
|
||||
err = nil
|
||||
|
||||
if em.PipeLineCommand != nil && len(em.PipeLineCommand) != 0 {
|
||||
// 管道命令
|
||||
resultLog, err = PipeLineCommandExecutor(em.PipeLineCommand)
|
||||
} else if em.MultiLineCommand != nil && len(em.MultiLineCommand) != 0 {
|
||||
// 多行命令
|
||||
resultLog, err = MultiLineCommandExecutor(em.MultiLineCommand)
|
||||
} else {
|
||||
// 单行命令
|
||||
resultLog, err = SingleLineCommandExecutor(em.SingleLineCommand)
|
||||
// shell command
|
||||
|
||||
if em.PipeLineCommand != nil && len(em.PipeLineCommand) != 0 {
|
||||
// 管道命令
|
||||
resultLog, err = PipeLineCommandExecutor(em.PipeLineCommand)
|
||||
realCommand = em.PipeLineCommand
|
||||
} else if em.MultiLineCommand != nil && len(em.MultiLineCommand) != 0 {
|
||||
// 多行命令
|
||||
resultLog, err = MultiLineCommandExecutor(em.MultiLineCommand)
|
||||
realCommand = em.MultiLineCommand
|
||||
} else {
|
||||
// 单行命令
|
||||
resultLog, err = SingleLineCommandExecutor(em.SingleLineCommand)
|
||||
realCommand = [][]string{em.SingleLineCommand}
|
||||
}
|
||||
}
|
||||
|
||||
// 归一化错误和日志
|
||||
@@ -33,69 +58,40 @@ func Execute(om *config.OctopusMessage, em *config.ExecutionMessage) ([]string,
|
||||
resultLog = append(resultLog, fmt.Sprintf("Error: %s", err.Error()))
|
||||
}
|
||||
|
||||
// 处理执行日志
|
||||
// 是否需要返回处理日志,现在默认返回
|
||||
if em.NeedResultReplay {
|
||||
// 需要返回处理结果
|
||||
om.ACTime = time.Now()
|
||||
om.Result = resultLog
|
||||
}
|
||||
commandResult := fmt.Sprintf("Excution Comand are=> %v, Executor Result: %v", realCommand, resultLog)
|
||||
|
||||
log.Info(fmt.Sprintf("Executor Result: %s", resultLog))
|
||||
log.Info(commandResult)
|
||||
|
||||
return resultLog, err
|
||||
}
|
||||
|
||||
func PipeLineCommandExecutor(pipeLineCommand [][]string) ([]string, error) {
|
||||
|
||||
var cmds []*exec.Cmd
|
||||
|
||||
// 创建每个命令对象,并将前一个命令的标准输出连接到当前命令的标准输入
|
||||
for i, partOfCommand := range pipeLineCommand {
|
||||
cmd := exec.Command(partOfCommand[0], partOfCommand[1:]...)
|
||||
if i > 0 {
|
||||
prevCmd := cmds[i-1]
|
||||
out, err := prevCmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd.Stdin = out
|
||||
var output []byte
|
||||
var err error
|
||||
for i, command := range pipeLineCommand {
|
||||
cmd := exec.Command(command[0], command[1:]...)
|
||||
cmd.Stdin = bytes.NewReader(output)
|
||||
output, err = cmd.Output()
|
||||
if err != nil {
|
||||
return strings.Split(string(output), "\n"), err
|
||||
}
|
||||
if i == len(pipeLineCommand)-1 {
|
||||
return strings.Split(string(output), "\n"), nil
|
||||
}
|
||||
cmds = append(cmds, cmd)
|
||||
}
|
||||
|
||||
// 执行最后一个命令,并获取其输出
|
||||
lastCmd := cmds[len(cmds)-1]
|
||||
|
||||
var out bytes.Buffer
|
||||
|
||||
lastCmd.Stdout = &out
|
||||
lastCmd.Stderr = &out
|
||||
err := lastCmd.Run()
|
||||
|
||||
scanner := bufio.NewScanner(&out)
|
||||
var result []string
|
||||
for scanner.Scan() {
|
||||
result = append(result, scanner.Text())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
return []string{}, nil
|
||||
}
|
||||
|
||||
func MultiLineCommandExecutor(multiLineCommandExecutor [][]string) ([]string, error) {
|
||||
|
||||
var res []string
|
||||
|
||||
for _, singleLineCommand := range multiLineCommandExecutor {
|
||||
|
||||
singleLogs, err := SingleLineCommandExecutor(singleLineCommand)
|
||||
res := append(res, singleLogs...)
|
||||
res = append(res, singleLogs...)
|
||||
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("Execution error ! command is %v, error is %v", singleLineCommand, err))
|
||||
return res, err
|
||||
}
|
||||
|
||||
@@ -118,7 +114,6 @@ func SingleLineCommandExecutor(singleLineCommand []string) ([]string, error) {
|
||||
var result []string
|
||||
for scanner.Scan() {
|
||||
result = append(result, scanner.Text())
|
||||
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
||||
81
agent-go/executor/RealTimeExecutor.go
Normal file
81
agent-go/executor/RealTimeExecutor.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package executor
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
func ReadTimeCommandExecutor(singleLineCommand []string) {
|
||||
cmd := exec.Command(singleLineCommand[0], singleLineCommand[1:]...)
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
log.ErrorF("command %v stdout error => %v", singleLineCommand, err)
|
||||
}
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
log.ErrorF("command %v stderr error => %v", singleLineCommand, err)
|
||||
}
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
log.ErrorF("command %v runtime error => %v", singleLineCommand, err)
|
||||
}
|
||||
|
||||
go realTimeOutput(stdout)
|
||||
go realTimeOutput(stderr)
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
log.ErrorF("command %v result error => %v", singleLineCommand, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func AllOutputCommandExecutor(singleLineCommand []string) []string {
|
||||
|
||||
cmd := exec.Command(singleLineCommand[0], singleLineCommand[1:]...)
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
log.ErrorF("command %v stdout error => %v", singleLineCommand, err)
|
||||
}
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if err != nil {
|
||||
log.ErrorF("command %v stderr error => %v", singleLineCommand, err)
|
||||
}
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
log.ErrorF("command %v runtime error => %v", singleLineCommand, err)
|
||||
}
|
||||
|
||||
var resultSlice []string
|
||||
resultSlice = append(resultSlice, collectOutput(stdout, resultSlice)...)
|
||||
resultSlice = append(resultSlice, collectOutput(stderr, resultSlice)...)
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
log.ErrorF("command %v result error => %v", singleLineCommand, err)
|
||||
}
|
||||
|
||||
//log.DebugF("real time exec result are %v", resultSlice)
|
||||
|
||||
return resultSlice
|
||||
}
|
||||
|
||||
func realTimeOutput(r io.Reader) {
|
||||
scanner := bufio.NewScanner(r)
|
||||
for scanner.Scan() {
|
||||
fmt.Println(scanner.Text())
|
||||
}
|
||||
}
|
||||
|
||||
func collectOutput(r io.Reader, resultSlice []string) []string {
|
||||
scanner := bufio.NewScanner(r)
|
||||
for scanner.Scan() {
|
||||
resultLine := scanner.Text()
|
||||
|
||||
resultSlice = append(resultSlice, resultLine)
|
||||
// debug usage
|
||||
//fmt.Println(resultLine)
|
||||
}
|
||||
|
||||
return resultSlice
|
||||
}
|
||||
13
agent-go/executor/RealTimeExecutor_test.go
Normal file
13
agent-go/executor/RealTimeExecutor_test.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package executor
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestReadTimeOutput(t *testing.T) {
|
||||
strings := []string{
|
||||
"/bin/bash",
|
||||
"/root/IdeaProjects/ProjectOctopus/agent-go/tmp/simple.sh",
|
||||
}
|
||||
|
||||
AllOutputCommandExecutor(strings)
|
||||
|
||||
}
|
||||
2016
agent-go/executor/script/1_node_important.sh
Normal file
2016
agent-go/executor/script/1_node_important.sh
Normal file
File diff suppressed because it is too large
Load Diff
2
agent-go/executor/script/shutdownFirewall.txt
Normal file
2
agent-go/executor/script/shutdownFirewall.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
systemctl stop firewalld
|
||||
systemctl disable firewalld
|
||||
@@ -1 +0,0 @@
|
||||
package g
|
||||
@@ -1,172 +0,0 @@
|
||||
package g
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/nacos-group/nacos-sdk-go/v2/clients"
|
||||
"github.com/nacos-group/nacos-sdk-go/v2/clients/config_client"
|
||||
"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
|
||||
"github.com/nacos-group/nacos-sdk-go/v2/vo"
|
||||
"github.com/spf13/viper"
|
||||
"go.uber.org/zap"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var log = G.LOG
|
||||
var group = ""
|
||||
|
||||
func InitNacos(configFileName string) *viper.Viper {
|
||||
|
||||
v := parseAgentConfigFile(configFileName, nil)
|
||||
group = v.GetString("spring.cloud.nacos.config.group")
|
||||
|
||||
// build the nacos connection
|
||||
configClient := startNacosConnection(v)
|
||||
|
||||
// get all needed nacos config and merge
|
||||
allNacosConfig := getAllNacosConfig(v, group, configClient)
|
||||
|
||||
for _, nacosConfigContent := range allNacosConfig {
|
||||
log.Debug(fmt.Sprintf("nacos config conetent is %s", nacosConfigContent))
|
||||
|
||||
parseNacosConfigContend(nacosConfigContent, v)
|
||||
}
|
||||
|
||||
log.Info(fmt.Sprintf("%s config read result are %v", configFileName, v.AllSettings()))
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func parseAgentConfigFile(configFileName string, v *viper.Viper) *viper.Viper {
|
||||
|
||||
// 使用Viper框架读取
|
||||
if v == nil {
|
||||
v = viper.New()
|
||||
}
|
||||
|
||||
// 设置配置文件路径和名称
|
||||
v.SetConfigName(configFileName)
|
||||
v.AddConfigPath(".")
|
||||
v.SetConfigType("yaml")
|
||||
|
||||
// 读取默认的总配置文件
|
||||
err := v.ReadInConfig()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("fatal error config file: %s", err))
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func parseNacosConfigContend(configContent string, v *viper.Viper) *viper.Viper {
|
||||
|
||||
v.SetConfigType("yaml")
|
||||
|
||||
// use merge
|
||||
|
||||
err := v.MergeConfig(bytes.NewBuffer([]byte(configContent)))
|
||||
if err != nil {
|
||||
log.Error("nacos config contend read error !", zap.Error(err))
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
func startNacosConnection(v *viper.Viper) config_client.IConfigClient {
|
||||
|
||||
serverAddr := v.GetString("spring.cloud.nacos.config.server-addr")
|
||||
|
||||
clientConfig := constant.ClientConfig{
|
||||
//Endpoint: serverAddr,
|
||||
NamespaceId: "",
|
||||
TimeoutMs: v.GetUint64("spring.cloud.nacos.config.timeout"),
|
||||
NotLoadCacheAtStart: true,
|
||||
AppendToStdout: true,
|
||||
UpdateCacheWhenEmpty: true,
|
||||
//LogDir: "/tmp/nacos/log",
|
||||
//CacheDir: "/tmp/nacos/cache",
|
||||
Username: "nacos",
|
||||
Password: "Superwmm.23",
|
||||
}
|
||||
|
||||
split := strings.Split(serverAddr, ":")
|
||||
if len(split) != 2 {
|
||||
log.Error("nacos server addr error!")
|
||||
}
|
||||
|
||||
port, _ := strconv.ParseUint(split[1], 10, 64)
|
||||
serverConfigs := []constant.ServerConfig{
|
||||
{
|
||||
IpAddr: split[0],
|
||||
Port: port,
|
||||
GrpcPort: port + 1000,
|
||||
},
|
||||
}
|
||||
|
||||
// Another way of create config client for dynamic configuration (recommend)
|
||||
configClient, err := clients.NewConfigClient(
|
||||
vo.NacosClientParam{
|
||||
ClientConfig: &clientConfig,
|
||||
ServerConfigs: serverConfigs,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return configClient
|
||||
}
|
||||
|
||||
func getAllNacosConfig(v *viper.Viper, group string, configClient config_client.IConfigClient) []string {
|
||||
|
||||
result := make([]string, 0)
|
||||
|
||||
// main nacos configs
|
||||
mainNacosConfigFileName := v.GetString("spring.application.name") + "-" + v.GetString("spring.profiles.active") + "." + v.GetString("spring.cloud.nacos.config.file-extension")
|
||||
|
||||
log.Debug(fmt.Sprintf("main nacos config file name is %s", mainNacosConfigFileName))
|
||||
configContent := getConfig(mainNacosConfigFileName, group, configClient)
|
||||
result = append(result, configContent)
|
||||
|
||||
// additional nacos config
|
||||
additionalNacosConfig := v.Get("spring.cloud.nacos.config.extension-configs")
|
||||
// 增加断言,判定map的类型
|
||||
m, ok := additionalNacosConfig.([]interface{})
|
||||
if !ok {
|
||||
fmt.Println("additionalNacosConfig is not a slice")
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, addConfigMap := range m {
|
||||
|
||||
realMap, _ := addConfigMap.(map[string]interface{})
|
||||
|
||||
// 拿到配置的Key
|
||||
dataId := realMap["data-id"].(string)
|
||||
group := realMap["group"].(string)
|
||||
|
||||
// 查询
|
||||
config := getConfig(dataId, group, configClient)
|
||||
result = append(result, config)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// getConfig 从Nacos中获取相应的
|
||||
func getConfig(dataId string, group string, configClient config_client.IConfigClient) string {
|
||||
|
||||
log.Debug(fmt.Sprintf("nacos config get method dataID is %s, group is %s", dataId, group))
|
||||
|
||||
content, err := configClient.GetConfig(vo.ConfigParam{
|
||||
DataId: dataId,
|
||||
Group: group,
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("nacos config get error !", zap.Error(err))
|
||||
}
|
||||
|
||||
log.Debug(fmt.Sprintf("dataId %s , group %s, nacos config content is %s", dataId, group, content))
|
||||
|
||||
return content
|
||||
}
|
||||
@@ -1,16 +1,15 @@
|
||||
package g
|
||||
|
||||
import (
|
||||
"agent-go/config"
|
||||
logger2 "agent-go/logger"
|
||||
"github.com/panjf2000/ants/v2"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type Global struct {
|
||||
LOG *Logger
|
||||
NacosConfig *viper.Viper
|
||||
AgentServerInfo *config.AgentServerInfo
|
||||
P *ants.Pool
|
||||
AgentHasRegister bool
|
||||
AgentConfig *viper.Viper
|
||||
P *ants.Pool
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -19,23 +18,22 @@ const (
|
||||
ExecOmType = "EXECUTOR"
|
||||
StatusOmType = "STATUS"
|
||||
InitOmType = "INIT"
|
||||
AgentOmType = "AGENT"
|
||||
|
||||
BaseFuncOssUrlPrefix = "https://b2.107421.xyz/"
|
||||
)
|
||||
|
||||
var logger, _ = NewLogger()
|
||||
|
||||
var pool, _ = ants.NewPool(100, ants.WithNonblocking(true), ants.WithLogger(logger))
|
||||
var pool, _ = ants.NewPool(100, ants.WithNonblocking(false), ants.WithLogger(logger2.Log), ants.WithMaxBlockingTasks(30), ants.WithDisablePurge(true))
|
||||
|
||||
var G = NewGlobal(
|
||||
logger,
|
||||
pool,
|
||||
)
|
||||
|
||||
// NewGlobal NewGlobal构造函数返回一个新的Global实例,其中包含指定的Logger。
|
||||
func NewGlobal(logger *Logger, pool *ants.Pool) *Global {
|
||||
func NewGlobal(pool *ants.Pool) *Global {
|
||||
return &Global{
|
||||
LOG: logger,
|
||||
NacosConfig: nil,
|
||||
AgentServerInfo: nil,
|
||||
P: pool,
|
||||
AgentHasRegister: false,
|
||||
AgentConfig: nil,
|
||||
P: pool,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ go 1.18
|
||||
require (
|
||||
github.com/nacos-group/nacos-sdk-go/v2 v2.2.0
|
||||
github.com/panjf2000/ants/v2 v2.7.2
|
||||
github.com/shirou/gopsutil/v3 v3.23.3
|
||||
github.com/spf13/viper v1.15.0
|
||||
github.com/streadway/amqp v1.0.0
|
||||
go.uber.org/zap v1.24.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -17,11 +17,13 @@ require (
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
@@ -29,20 +31,25 @@ require (
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/prometheus/client_golang v1.12.2 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.32.1 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.4 // indirect
|
||||
github.com/spf13/afero v1.9.3 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.11 // indirect
|
||||
github.com/tklauser/numcpus v0.6.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.8.0 // indirect
|
||||
golang.org/x/net v0.4.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.3.0 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/text v0.5.0 // indirect
|
||||
golang.org/x/time v0.1.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect
|
||||
@@ -50,4 +57,5 @@ require (
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -93,6 +93,8 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
|
||||
@@ -140,6 +142,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
@@ -189,6 +192,8 @@ github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
@@ -217,6 +222,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
@@ -242,6 +249,12 @@ github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/shirou/gopsutil/v3 v3.23.3 h1:Syt5vVZXUDXPEXpIBt5ziWsJ4LdSAAxF4l/xZeQgSEE=
|
||||
github.com/shirou/gopsutil/v3 v3.23.3/go.mod h1:lSBNN6t3+D6W5e5nXTxc8KIMMVxAcS+6IJlffjRRlMU=
|
||||
github.com/shoenig/go-m1cpu v0.1.4 h1:SZPIgRM2sEF9NJy50mRHu9PKGwxyyTTJIWvCtgVbozs=
|
||||
github.com/shoenig/go-m1cpu v0.1.4/go.mod h1:Wwvst4LR89UxjeFtLRMrpgRiyY4xPsejnVZym39dbAQ=
|
||||
github.com/shoenig/test v0.6.3 h1:GVXWJFk9PiOjN0KoJ7VrJGH6uLPnqxR7/fe3HUPfE0c=
|
||||
github.com/shoenig/test v0.6.3/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
@@ -268,15 +281,22 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
|
||||
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
||||
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
|
||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
@@ -410,6 +430,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -433,6 +454,7 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -445,8 +467,9 @@ golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package g
|
||||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -11,6 +11,8 @@ type Logger struct {
|
||||
*zap.Logger
|
||||
}
|
||||
|
||||
var Log, _ = NewLogger()
|
||||
|
||||
// NewLogger creates a new Logger instance.
|
||||
func NewLogger() (*Logger, error) {
|
||||
config := zap.Config{
|
||||
@@ -23,7 +25,7 @@ func NewLogger() (*Logger, error) {
|
||||
LevelKey: "level",
|
||||
TimeKey: "time",
|
||||
//CallerKey: "caller",
|
||||
EncodeLevel: zapcore.CapitalColorLevelEncoder,
|
||||
EncodeLevel: zapcore.CapitalLevelEncoder,
|
||||
EncodeTime: zapcore.RFC3339TimeEncoder,
|
||||
//EncodeCaller: zapcore.FullCallerEncoder,
|
||||
},
|
||||
@@ -65,8 +67,9 @@ func (l *Logger) Warn(msg string, fields ...zap.Field) {
|
||||
}
|
||||
|
||||
// Error logs an error message.
|
||||
func (l *Logger) Error(msg string, fields ...zap.Field) {
|
||||
l.Logger.Error(msg, fields...)
|
||||
|
||||
func (l *Logger) ErrorF(msg string, args ...interface{}) {
|
||||
l.Logger.Error(fmt.Sprintf(msg, args...))
|
||||
}
|
||||
|
||||
// Fatal logs a fatal message and exits the program with a non-zero status code.
|
||||
@@ -2,12 +2,13 @@ package main
|
||||
|
||||
import (
|
||||
"agent-go/g"
|
||||
logger2 "agent-go/logger"
|
||||
"agent-go/register"
|
||||
"flag"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var log = g.G.LOG
|
||||
var log = logger2.Log
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -17,12 +18,12 @@ func main() {
|
||||
flag.Parse()
|
||||
// 读取对应版本的配置文件
|
||||
filename := fmt.Sprintf("octopus-agent-%s.yaml", version)
|
||||
println(filename)
|
||||
println("config file name is => " + filename)
|
||||
|
||||
// 初始化Nacos的连接配置
|
||||
g.G.NacosConfig = g.InitNacos(filename)
|
||||
g.G.AgentConfig = register.ParseConfiguration(filename)
|
||||
|
||||
// 执行初始化之策工作
|
||||
g.G.AgentServerInfo = register.INIT()
|
||||
AgentServerInfoCache = INIT()
|
||||
|
||||
}
|
||||
|
||||
@@ -1,22 +1,91 @@
|
||||
spring:
|
||||
application:
|
||||
name: octopus-agent
|
||||
profiles:
|
||||
active: dev
|
||||
cloud:
|
||||
nacos:
|
||||
config:
|
||||
group: dev
|
||||
config-retry-time: 3000
|
||||
file-extension: yaml
|
||||
max-retry: 3
|
||||
# server-addr: "150.230.198.103:21060"
|
||||
server-addr: "42.192.52.227:21060"
|
||||
timeout: 5000
|
||||
config-long-poll-timeout: 5000
|
||||
extension-configs:
|
||||
- group: dev
|
||||
data-id: "common-dev.yaml"
|
||||
|
||||
server:
|
||||
port: 8000
|
||||
port: 8000
|
||||
|
||||
logging:
|
||||
level:
|
||||
web: info
|
||||
|
||||
octopus:
|
||||
message:
|
||||
# agent boot up default common exchange
|
||||
init_exchange: InitExchange
|
||||
# server will send message to agent using this common queue
|
||||
init_to_server: InitToServer
|
||||
# agent boot up default common exchange routing key
|
||||
init_to_server_key: InitToServerKey
|
||||
# server will receive message from agent using this common queue
|
||||
init_from_server: InitFromServer
|
||||
# agent boot up default common exchange routing key
|
||||
init_from_server_key: InitFromServerKey
|
||||
# initialization register time out (unit ms) default is 5 min
|
||||
init_ttl: "3000000"
|
||||
# Octopus Exchange Name == server comunicate with agent
|
||||
octopus_exchange: OctopusExchange
|
||||
# Octopus Message To Server == all agent send info to server queue and topic
|
||||
octopus_to_server: OctopusToServer
|
||||
executor:
|
||||
name: executor-functions
|
||||
status:
|
||||
name: octopus-agent
|
||||
healthy:
|
||||
type: cron
|
||||
cron: 10 */1 * * * ? *
|
||||
start-delay: 30
|
||||
metric:
|
||||
pinch: 20
|
||||
agent:
|
||||
executor:
|
||||
# agent执行一条Command的最长超时时间
|
||||
processMaxTimeOut: 60
|
||||
status:
|
||||
app:
|
||||
- Nginx/nginx
|
||||
- MySQL/mysql
|
||||
- Xray/xray
|
||||
- OctopusAgent/octopus-agent
|
||||
- Redis/redis
|
||||
- RabbitMQ/rabbitmq
|
||||
|
||||
spring:
|
||||
main:
|
||||
allow-circular-references: true
|
||||
allow-bean-definition-overriding: true
|
||||
rabbitmq:
|
||||
# host: 42.192.52.227
|
||||
host: 192.168.35.71
|
||||
port: 20672
|
||||
username: boge
|
||||
password: boge8tingH
|
||||
virtual-host: /
|
||||
listener:
|
||||
simple:
|
||||
retry:
|
||||
# ack failed will reentrant the Rabbit Listener
|
||||
max-attempts: 2
|
||||
enabled: true
|
||||
# retry interval unit ms
|
||||
max-interval: 65000
|
||||
initial-interval: 65000
|
||||
|
||||
#spring:
|
||||
# application:
|
||||
# name: octopus-agent
|
||||
# profiles:
|
||||
# active: dev
|
||||
# cloud:
|
||||
# nacos:
|
||||
# config:
|
||||
# group: dev
|
||||
# config-retry-time: 3000
|
||||
# file-extension: yaml
|
||||
# max-retry: 3
|
||||
# # server-addr: "150.230.198.103:21060"
|
||||
# server-addr: "42.192.52.227:21060"
|
||||
# timeout: 5000
|
||||
# config-long-poll-timeout: 5000
|
||||
# extension-configs:
|
||||
# - group: dev
|
||||
# data-id: "common-dev.yaml"
|
||||
#
|
||||
#server:
|
||||
# port: 8000
|
||||
@@ -1,63 +0,0 @@
|
||||
package rabbitmq
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/nacos-group/nacos-sdk-go/v2/common/logger"
|
||||
"github.com/streadway/amqp"
|
||||
)
|
||||
|
||||
// RabbitMQConn is a struct that holds the connection and channel objects
|
||||
type RabbitMQConn struct {
|
||||
Connection *amqp.Connection
|
||||
Channel *amqp.Channel
|
||||
}
|
||||
|
||||
type ConnectProperty struct {
|
||||
ExchangeName string
|
||||
QueueName string
|
||||
ExchangeType string
|
||||
TopicKey string
|
||||
}
|
||||
|
||||
// Send 向RabbitMQ中发送消息
|
||||
func Send(conn *RabbitMQConn, connProp *ConnectProperty, message []byte) {
|
||||
// 往哪里发
|
||||
channel := conn.Channel
|
||||
|
||||
// 发送
|
||||
err := channel.Publish(
|
||||
connProp.ExchangeName,
|
||||
connProp.TopicKey,
|
||||
false,
|
||||
false,
|
||||
amqp.Publishing{
|
||||
ContentType: "text/plain",
|
||||
Body: message,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("Failed to publish a message: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
func Read(conn *RabbitMQConn, connProp *ConnectProperty, autoAck bool) <-chan amqp.Delivery {
|
||||
|
||||
// 拿到特定的Channel
|
||||
channel := conn.Channel
|
||||
|
||||
// 开始读取队列中的全部消息
|
||||
msgs, err := channel.Consume(
|
||||
connProp.QueueName, // 队列名称
|
||||
"", // 消费者名称
|
||||
autoAck, // auto-ack
|
||||
false, // exclusive
|
||||
false, // no-local
|
||||
false, // no-wait
|
||||
nil, // arguments
|
||||
)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("Failed to register a consumer: %v", err))
|
||||
}
|
||||
|
||||
return msgs
|
||||
}
|
||||
78
agent-go/rabbitmq/OMsgConnector.go
Normal file
78
agent-go/rabbitmq/OMsgConnector.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package rabbitmq
|
||||
|
||||
import (
|
||||
"agent-go/g"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var OctopusToServerQueue = &RabbitQueue{}
|
||||
|
||||
var P = g.G.P
|
||||
|
||||
func BuildOMsgRuntimeConnectorQueue(agentTopicName string) {
|
||||
|
||||
// 建立 业务消息 接收队列
|
||||
// agentTopicName为名称的队列
|
||||
agentConfig := g.G.AgentConfig
|
||||
|
||||
octopusExchangeName := agentConfig.GetString("octopus.message.octopus_exchange")
|
||||
|
||||
octopusConnectProp := &ConnectProperty{
|
||||
ExchangeName: octopusExchangeName,
|
||||
QueueName: agentTopicName,
|
||||
ExchangeType: g.QueueTopic,
|
||||
TopicKey: agentTopicName + "*",
|
||||
}
|
||||
|
||||
octopusMsgQueue := &RabbitQueue{
|
||||
RabbitProp: octopusConnectProp,
|
||||
}
|
||||
octopusMsgQueue.Connect()
|
||||
|
||||
// 建立 业务消息 返回队列
|
||||
// 统一为 OctopusToServer
|
||||
octopusToServerQueueName := agentConfig.GetString("octopus.message.octopus_to_server")
|
||||
|
||||
octopusToServerProp := &ConnectProperty{
|
||||
ExchangeName: octopusExchangeName,
|
||||
QueueName: octopusToServerQueueName,
|
||||
ExchangeType: g.QueueTopic,
|
||||
TopicKey: octopusToServerQueueName,
|
||||
}
|
||||
|
||||
OctopusToServerQueue = &RabbitQueue{
|
||||
RabbitProp: octopusToServerProp,
|
||||
}
|
||||
|
||||
// 开启运行时消息返回队列
|
||||
OctopusToServerQueue.Connect()
|
||||
|
||||
log.InfoF("Octopus Message Business Runtime Queue is established ! => %v", OctopusToServerQueue)
|
||||
|
||||
deliveries := octopusMsgQueue.Read(true)
|
||||
forever := make(chan bool)
|
||||
P.Submit(
|
||||
func() {
|
||||
// 死循环,处理Octopus Message
|
||||
for delivery := range deliveries {
|
||||
|
||||
var om *OctopusMessage
|
||||
err := json.Unmarshal(delivery.Body, &om)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("octopus message convert to json is wrong! msg is => %s", delivery.Body))
|
||||
// 保存到某处
|
||||
continue
|
||||
}
|
||||
|
||||
// 策略模式 处理消息
|
||||
P.Submit(func() {
|
||||
om.Handle()
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// wait forever
|
||||
<-forever
|
||||
|
||||
}
|
||||
186
agent-go/rabbitmq/OctopusMessage.go
Normal file
186
agent-go/rabbitmq/OctopusMessage.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package rabbitmq
|
||||
|
||||
import (
|
||||
"agent-go/executor"
|
||||
"agent-go/g"
|
||||
"agent-go/status"
|
||||
"agent-go/utils"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type IOctopusMessage interface {
|
||||
OctopusMsgHandler
|
||||
OctopusMsgSender
|
||||
OctopusMsgBuilder
|
||||
}
|
||||
|
||||
type OctopusMsgHandler interface {
|
||||
Handle(octopusMessage *OctopusMessage)
|
||||
}
|
||||
|
||||
type OctopusMsgSender interface {
|
||||
Send(rabbitQueue *RabbitQueue, msg []byte)
|
||||
|
||||
SendToOctopusServer()
|
||||
}
|
||||
|
||||
type OctopusMsgBuilder interface {
|
||||
Build(omType string, content interface{}) *OctopusMessage
|
||||
}
|
||||
|
||||
type OctopusMessage struct {
|
||||
UUID string `json:"uuid"`
|
||||
InitTime string `json:"init_time" format:"2023-03-21 16:38:30"`
|
||||
Type string `json:"type"`
|
||||
Content interface{} `json:"content"`
|
||||
Result interface{} `json:"result"`
|
||||
ResultCode string `json:"resultCode"`
|
||||
ACTime string `json:"ac_time" format:"2023-03-21 16:38:30"`
|
||||
}
|
||||
|
||||
func (om *OctopusMessage) Handle() {
|
||||
// 实际执行 OM handle进程
|
||||
doHandleOctopusMessage(om)
|
||||
}
|
||||
|
||||
func (om *OctopusMessage) Send(rabbitQueue *RabbitQueue, msg []byte) {
|
||||
rabbitQueue.Send(msg)
|
||||
}
|
||||
|
||||
// SendToOctopusServer send octopus message back to octopusToServer queue
|
||||
func (om *OctopusMessage) SendToOctopusServer() {
|
||||
|
||||
// write the octopus message to bytes
|
||||
octopusMessageReplayBytes, err := json.Marshal(om)
|
||||
if err != nil {
|
||||
log.ErrorF("replay octopus message write error => %v", err)
|
||||
}
|
||||
|
||||
// Send back the result to queue
|
||||
OctopusToServerQueue.Send(octopusMessageReplayBytes)
|
||||
|
||||
}
|
||||
|
||||
func (om *OctopusMessage) Build(omType string, content interface{}) *OctopusMessage {
|
||||
|
||||
// 当前时间
|
||||
curTimeString := utils.ParseDateTimeTime()
|
||||
|
||||
// must write to string format, otherwise it's very hard to deserialize
|
||||
bytes, err := json.Marshal(content)
|
||||
if err != nil {
|
||||
fmt.Sprintf("OctopusMessage Build Error ! %v", err)
|
||||
}
|
||||
|
||||
return &OctopusMessage{
|
||||
UUID: curTimeString,
|
||||
InitTime: curTimeString,
|
||||
Type: omType,
|
||||
Content: string(bytes),
|
||||
Result: nil,
|
||||
ACTime: curTimeString,
|
||||
}
|
||||
}
|
||||
|
||||
func doHandleOctopusMessage(octopusMessage *OctopusMessage) {
|
||||
|
||||
switch octopusMessage.Type {
|
||||
case g.InitOmType:
|
||||
go func() {}()
|
||||
case g.ExecOmType:
|
||||
P.Submit(func() {
|
||||
executorOMHandler(octopusMessage)
|
||||
})
|
||||
case g.StatusOmType:
|
||||
P.Submit(func() {
|
||||
statusOMHandler(octopusMessage)
|
||||
})
|
||||
case g.AgentOmType:
|
||||
P.Submit(func() {
|
||||
agentOMHandler(octopusMessage)
|
||||
},
|
||||
)
|
||||
default:
|
||||
P.Submit(func() {
|
||||
blackHoleOMHandler(octopusMessage)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// agentOMHandler 处理Agent的核心操作指令
|
||||
func agentOMHandler(octopusMessage *OctopusMessage) {
|
||||
|
||||
}
|
||||
|
||||
func executorOMHandler(octopusMessage *OctopusMessage) {
|
||||
|
||||
executionMsgString := octopusMessage.Content.(string)
|
||||
|
||||
var executionMessage *executor.ExecutionMessage
|
||||
err := json.Unmarshal([]byte(executionMsgString), &executionMessage)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("execution message convert to json is wrong! msg is => %s", executionMsgString))
|
||||
return
|
||||
}
|
||||
|
||||
// 交给后端的实际处理器处理, 再次策略
|
||||
resultLog, err := executor.Execute(executionMessage)
|
||||
if err != nil {
|
||||
octopusMessage.ResultCode = "200"
|
||||
} else {
|
||||
octopusMessage.ResultCode = "300"
|
||||
}
|
||||
|
||||
// send back the result log
|
||||
octopusMessage.Result = resultLog
|
||||
octopusMessage.ACTime = utils.ParseISOLocalDateTime()
|
||||
|
||||
// Send
|
||||
octopusMessage.SendToOctopusServer()
|
||||
}
|
||||
|
||||
func statusOMHandler(octopusMessage *OctopusMessage) {
|
||||
|
||||
v, ok := (octopusMessage.Content).(string)
|
||||
if !ok {
|
||||
log.ErrorF("convert to string is wrong %s", v)
|
||||
}
|
||||
|
||||
statusMsgString := octopusMessage.Content.(string)
|
||||
|
||||
var statusMessage *status.StatusMessage
|
||||
err := json.Unmarshal([]byte(statusMsgString), &statusMessage)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
log.Error(fmt.Sprintf("status message convert to json is wrong! msg is => %s", octopusMessage))
|
||||
return
|
||||
}
|
||||
|
||||
var statusRes string
|
||||
if strings.HasPrefix(statusMessage.StatusType, "P") {
|
||||
// ping info
|
||||
statusRes = status.Ping()
|
||||
} else {
|
||||
// status info
|
||||
agentStatusString, _ := json.Marshal(status.ReportAppStatus())
|
||||
statusRes = string(agentStatusString)
|
||||
}
|
||||
|
||||
// 返回消息
|
||||
// 组装消息
|
||||
octopusMessage.ACTime = utils.ParseDateTimeTime()
|
||||
octopusMessage.Result = statusRes
|
||||
// 发送回去
|
||||
statusOctopusReplayMessage, _ := json.Marshal(octopusMessage)
|
||||
OctopusToServerQueue.Send(statusOctopusReplayMessage)
|
||||
|
||||
// 输出日志
|
||||
log.InfoF("接收到查询Agent状态的请求,结果为 => %s", statusRes)
|
||||
}
|
||||
|
||||
func blackHoleOMHandler(octopusMessage *OctopusMessage) {
|
||||
log.Error(fmt.Sprintf("[BLACK HOLE] octopusMessage type wrong! msg is => %v", octopusMessage))
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
package rabbitmq
|
||||
|
||||
import (
|
||||
"agent-go/config"
|
||||
"agent-go/executor"
|
||||
"agent-go/g"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var P = g.G.P
|
||||
|
||||
func HandleOMsg(initOMsgFromServer *config.OctopusMessage) {
|
||||
|
||||
agentTopicName := initOMsgFromServer.Result.(string)
|
||||
|
||||
OctopusExchange := g.G.NacosConfig.GetString("octopus.message.octopus_exchange")
|
||||
|
||||
octopusConnectProp := &ConnectProperty{
|
||||
ExchangeName: OctopusExchange,
|
||||
QueueName: agentTopicName,
|
||||
ExchangeType: g.QueueTopic,
|
||||
TopicKey: agentTopicName + "*",
|
||||
}
|
||||
|
||||
octopusConn, err := NewRabbitMQConn(octopusConnectProp)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("Octopus Message Queue create Error ! => %v", octopusConnectProp))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 开始接收消息
|
||||
channel := octopusConn.Channel
|
||||
deliveries, err := channel.Consume(
|
||||
agentTopicName,
|
||||
agentTopicName,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// 死循环,处理Ocotpus Message
|
||||
for delivery := range deliveries {
|
||||
|
||||
var om *config.OctopusMessage
|
||||
err := json.Unmarshal(delivery.Body, &om)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("octopus message convert to json is wrong! msg is => %s", delivery.Body))
|
||||
// 保存到某处
|
||||
continue
|
||||
}
|
||||
|
||||
// 策略模式 处理消息
|
||||
doHandleOctopusMessage(om)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func doHandleOctopusMessage(octopusMessage *config.OctopusMessage) {
|
||||
|
||||
switch octopusMessage.Type {
|
||||
case g.InitOmType:
|
||||
go func() {}()
|
||||
case g.ExecOmType:
|
||||
P.Submit(func() {
|
||||
executorOMHandler(octopusMessage)
|
||||
})
|
||||
case g.StatusOmType:
|
||||
P.Submit(func() {
|
||||
statusOMHandler(octopusMessage)
|
||||
})
|
||||
default:
|
||||
P.Submit(func() {
|
||||
blackHoleOMHandler(octopusMessage)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func executorOMHandler(octopusMessage *config.OctopusMessage) {
|
||||
|
||||
executionMsgString := octopusMessage.Content.(string)
|
||||
|
||||
var executionMessage *config.ExecutionMessage
|
||||
err := json.Unmarshal([]byte(executionMsgString), &executionMessage)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("execution message convert to json is wrong! msg is => %s", executionMsgString))
|
||||
return
|
||||
}
|
||||
|
||||
// 交给后端的实际处理器处理, 再次策略
|
||||
executor.Execute(octopusMessage, executionMessage)
|
||||
}
|
||||
|
||||
func statusOMHandler(octopusMessage *config.OctopusMessage) {
|
||||
|
||||
}
|
||||
|
||||
func blackHoleOMHandler(octopusMessage *config.OctopusMessage) {
|
||||
log.Error(fmt.Sprintf("octopusMessage type wrong! msg is => %v", octopusMessage))
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
package rabbitmq
|
||||
|
||||
import (
|
||||
"agent-go/g"
|
||||
"fmt"
|
||||
"github.com/streadway/amqp"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var log = g.G.LOG
|
||||
|
||||
// 定义全局唯一的 Singleton 实例
|
||||
var instance *amqp.Connection
|
||||
|
||||
// 用 sync.Once 变量确保初始化函数只会被调用一次
|
||||
var once sync.Once
|
||||
|
||||
// 初始化 Singleton 实例的函数
|
||||
func createInstance() {
|
||||
// 在这里进行 Singleton 的初始化操作
|
||||
|
||||
// 获取RabbitMQ的连接地址
|
||||
rabbitMQEndpointFromG := parseRabbitMQEndpointFromG()
|
||||
|
||||
// 创建全局唯一连接 RabbitMQ连接
|
||||
connection, err := amqp.Dial(rabbitMQEndpointFromG)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("failed to connect to RabbitMQ: %v", err))
|
||||
}
|
||||
|
||||
instance = connection
|
||||
}
|
||||
|
||||
// GetInstance 获取全局唯一的 Singleton 实例的函数
|
||||
func GetInstance() *amqp.Connection {
|
||||
// 使用 sync.Once 确保 createInstance 只会被调用一次
|
||||
once.Do(createInstance)
|
||||
return instance
|
||||
}
|
||||
|
||||
// NewRabbitMQConn creates a new RabbitMQ connection object
|
||||
func NewRabbitMQConn(property *ConnectProperty) (*RabbitMQConn, error) {
|
||||
|
||||
// 获取RabbitMQ的连接
|
||||
conn := GetInstance()
|
||||
// 获取RabbitMQ的连接地址
|
||||
//rabbitMQEndpointFromG := parseRabbitMQEndpointFromG()
|
||||
//conn, err := amqp.Dial(rabbitMQEndpointFromG)
|
||||
//if err != nil {
|
||||
// log.Error(fmt.Sprintf("failed to connect to RabbitMQ: %v", err))
|
||||
//}
|
||||
|
||||
ch, err := conn.Channel()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create RabbitMQ channel: %w", err)
|
||||
}
|
||||
|
||||
if err = ch.ExchangeDeclare(
|
||||
property.ExchangeName, // name of the exchange
|
||||
property.ExchangeType, // type of the exchange
|
||||
false, // durable
|
||||
false, // delete when complete
|
||||
false, // internal
|
||||
false, // noWait
|
||||
nil, // arguments
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("failed to declare RabbitMQ exchange: %w", err)
|
||||
}
|
||||
|
||||
_, err = ch.QueueDeclare(
|
||||
property.QueueName, // name of the queue
|
||||
false, // durable
|
||||
false, // delete when unused
|
||||
false, // exclusive
|
||||
false, // noWait
|
||||
nil, // arguments
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to declare RabbitMQ queue: %w", err)
|
||||
}
|
||||
|
||||
if err = ch.QueueBind(
|
||||
property.QueueName, // name of the queue
|
||||
property.TopicKey, // routing key - all topics
|
||||
property.ExchangeName, // name of the exchange
|
||||
false, // noWait
|
||||
nil, // arguments
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("failed to bind RabbitMQ queue: %w", err)
|
||||
}
|
||||
|
||||
return &RabbitMQConn{Connection: conn, Channel: ch}, nil
|
||||
}
|
||||
|
||||
// parseRabbitMQEndpoint 根据全局变量NacosConfig解析出RabbitMQ的连接地址
|
||||
func parseRabbitMQEndpointFromG() string {
|
||||
|
||||
nacosConfig := g.G.NacosConfig
|
||||
|
||||
var res strings.Builder
|
||||
|
||||
host := nacosConfig.GetString("spring.rabbitmq.host")
|
||||
port := nacosConfig.GetString("spring.rabbitmq.port")
|
||||
username := nacosConfig.GetString("spring.rabbitmq.username")
|
||||
password := nacosConfig.GetString("spring.rabbitmq.password")
|
||||
virtualHost := nacosConfig.GetString("spring.rabbitmq.virtual-host")
|
||||
|
||||
// amqp://{username}:{password}@{hostname}:{port}/{virtual_host}
|
||||
res.WriteString("amqp://")
|
||||
res.WriteString(username)
|
||||
res.WriteString(":")
|
||||
res.WriteString(password)
|
||||
res.WriteString("@")
|
||||
res.WriteString(host)
|
||||
res.WriteString(":")
|
||||
res.WriteString(port)
|
||||
res.WriteString("/")
|
||||
res.WriteString(virtualHost)
|
||||
|
||||
s := res.String()
|
||||
log.Debug(fmt.Sprintf("generate RabbitMQ endpoint is %s", s))
|
||||
return s
|
||||
}
|
||||
|
||||
func CloseChannel(conn *RabbitMQConn) error {
|
||||
var err error
|
||||
|
||||
if conn.Channel != nil {
|
||||
if err = conn.Channel.Close(); err != nil {
|
||||
log.Error(fmt.Sprintf("Failed to close RabbitMQ channel: %v", err))
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// CloseRabbitMQAll closes the RabbitMQ connection and channel
|
||||
func (r *RabbitMQConn) CloseRabbitMQAll() error {
|
||||
var err error
|
||||
|
||||
if r.Channel != nil {
|
||||
if err = r.Channel.Close(); err != nil {
|
||||
log.Error(fmt.Sprintf("Failed to close RabbitMQ channel: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
if r.Connection != nil {
|
||||
if err = r.Connection.Close(); err != nil {
|
||||
log.Error(fmt.Sprintf("Failed to close RabbitMQ connection: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
214
agent-go/rabbitmq/RabbitMsgQueue.go
Normal file
214
agent-go/rabbitmq/RabbitMsgQueue.go
Normal file
@@ -0,0 +1,214 @@
|
||||
package rabbitmq
|
||||
|
||||
import (
|
||||
"agent-go/g"
|
||||
logger2 "agent-go/logger"
|
||||
"fmt"
|
||||
"github.com/streadway/amqp"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type RabbitMQ interface {
|
||||
RabbitSendWriter
|
||||
|
||||
RabbitConnectCloser
|
||||
}
|
||||
|
||||
type RabbitSendWriter interface {
|
||||
Send(message []byte)
|
||||
|
||||
Read(autoAck bool) <-chan amqp.Delivery
|
||||
}
|
||||
|
||||
type RabbitConnectCloser interface {
|
||||
Connect()
|
||||
|
||||
Close() error
|
||||
}
|
||||
|
||||
type RabbitQueue struct {
|
||||
RabbitConn *RabbitMQConn
|
||||
RabbitProp *ConnectProperty
|
||||
}
|
||||
|
||||
// RabbitMQConn is a struct that holds the connection and channel objects
|
||||
type RabbitMQConn struct {
|
||||
Connection *amqp.Connection
|
||||
Channel *amqp.Channel
|
||||
}
|
||||
|
||||
type ConnectProperty struct {
|
||||
ExchangeName string
|
||||
QueueName string
|
||||
ExchangeType string
|
||||
TopicKey string
|
||||
}
|
||||
|
||||
var log = logger2.Log
|
||||
|
||||
// 定义全局唯一的 Singleton 实例
|
||||
var instance *amqp.Connection
|
||||
|
||||
// 用 sync.Once 变量确保初始化函数只会被调用一次
|
||||
var once sync.Once
|
||||
|
||||
// 初始化 Singleton 实例的函数
|
||||
func createInstance() {
|
||||
// 在这里进行 Singleton 的初始化操作
|
||||
|
||||
// 获取RabbitMQ的连接地址
|
||||
rabbitMQEndpointFromG := parseRabbitMQEndpointFromG()
|
||||
|
||||
// 创建全局唯一连接 RabbitMQ连接
|
||||
connection, err := amqp.Dial(rabbitMQEndpointFromG)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("failed to connect to RabbitMQ: %v", err))
|
||||
}
|
||||
|
||||
instance = connection
|
||||
}
|
||||
|
||||
// GetInstance 获取全局唯一的 Singleton 实例的函数
|
||||
func GetInstance() *amqp.Connection {
|
||||
// 使用 sync.Once 确保 createInstance 只会被调用一次
|
||||
once.Do(createInstance)
|
||||
return instance
|
||||
}
|
||||
|
||||
// Connect creates a new RabbitMQ connection object
|
||||
func (r *RabbitQueue) Connect() {
|
||||
|
||||
// 获取RabbitMQ的连接
|
||||
conn := GetInstance()
|
||||
|
||||
ch, err := conn.Channel()
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("failed to create RabbitMQ channel: %w", err))
|
||||
}
|
||||
|
||||
if err = ch.ExchangeDeclare(
|
||||
r.RabbitProp.ExchangeName, // name of the exchange
|
||||
r.RabbitProp.ExchangeType, // type of the exchange
|
||||
true, // durable
|
||||
false, // delete when complete
|
||||
false, // internal
|
||||
false, // noWait
|
||||
nil, // arguments
|
||||
); err != nil {
|
||||
log.Error(fmt.Sprintf("failed to declare exchange !: %w", err))
|
||||
}
|
||||
|
||||
_, err = ch.QueueDeclare(
|
||||
r.RabbitProp.QueueName, // name of the queue
|
||||
true, // durable
|
||||
false, // delete when unused
|
||||
false, // exclusive
|
||||
false, // noWait
|
||||
nil, // arguments
|
||||
)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("failed to declare RabbitMQ queue: %w", err))
|
||||
}
|
||||
|
||||
if err = ch.QueueBind(
|
||||
r.RabbitProp.QueueName, // name of the queue
|
||||
r.RabbitProp.TopicKey, // routing key - all topics
|
||||
r.RabbitProp.ExchangeName, // name of the exchange
|
||||
false, // noWait
|
||||
nil, // arguments
|
||||
); err != nil {
|
||||
log.Error(fmt.Sprintf("failed to bind RabbitMQ queue: %w", err))
|
||||
}
|
||||
|
||||
r.RabbitConn = &RabbitMQConn{
|
||||
Connection: conn,
|
||||
Channel: ch,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RabbitQueue) Close() error {
|
||||
var err error
|
||||
|
||||
if r.RabbitConn.Channel != nil {
|
||||
if err = r.RabbitConn.Channel.Close(); err != nil {
|
||||
log.Error(fmt.Sprintf("Failed to close RabbitMQ channel: %v", err))
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Send 向RabbitMQ中发送消息
|
||||
func (r *RabbitQueue) Send(message []byte) {
|
||||
// 往哪里发
|
||||
channel := r.RabbitConn.Channel
|
||||
|
||||
// 发送
|
||||
err := channel.Publish(
|
||||
r.RabbitProp.ExchangeName,
|
||||
r.RabbitProp.TopicKey,
|
||||
false,
|
||||
false,
|
||||
amqp.Publishing{
|
||||
ContentType: "text/plain",
|
||||
Body: message,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("Failed to publish a message: %v", err))
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RabbitQueue) Read(autoAck bool) <-chan amqp.Delivery {
|
||||
|
||||
// 拿到特定的Channel
|
||||
channel := r.RabbitConn.Channel
|
||||
|
||||
// 开始读取队列中的全部消息
|
||||
msgs, err := channel.Consume(
|
||||
r.RabbitProp.QueueName, // 队列名称
|
||||
"", // 消费者名称
|
||||
autoAck, // auto-ack
|
||||
false, // exclusive
|
||||
false, // no-local
|
||||
false, // no-wait
|
||||
nil, // arguments
|
||||
)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("Failed to register a consumer: %v", err))
|
||||
}
|
||||
|
||||
return msgs
|
||||
}
|
||||
|
||||
// parseRabbitMQEndpoint 根据全局变量agentConfig解析出RabbitMQ的连接地址
|
||||
func parseRabbitMQEndpointFromG() string {
|
||||
|
||||
agentConfig := g.G.AgentConfig
|
||||
|
||||
var res strings.Builder
|
||||
|
||||
host := agentConfig.GetString("spring.rabbitmq.host")
|
||||
port := agentConfig.GetString("spring.rabbitmq.port")
|
||||
username := agentConfig.GetString("spring.rabbitmq.username")
|
||||
password := agentConfig.GetString("spring.rabbitmq.password")
|
||||
virtualHost := agentConfig.GetString("spring.rabbitmq.virtual-host")
|
||||
|
||||
// amqp://{username}:{password}@{hostname}:{port}/{virtual_host}
|
||||
res.WriteString("amqp://")
|
||||
res.WriteString(username)
|
||||
res.WriteString(":")
|
||||
res.WriteString(password)
|
||||
res.WriteString("@")
|
||||
res.WriteString(host)
|
||||
res.WriteString(":")
|
||||
res.WriteString(port)
|
||||
res.WriteString("/")
|
||||
res.WriteString(virtualHost)
|
||||
|
||||
s := res.String()
|
||||
|
||||
log.Debug(fmt.Sprintf("generate RabbitMQ endpoint is %s", s))
|
||||
|
||||
return s
|
||||
}
|
||||
@@ -1,173 +0,0 @@
|
||||
package register
|
||||
|
||||
import (
|
||||
"agent-go/config"
|
||||
"agent-go/g"
|
||||
"agent-go/rabbitmq"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"gopkg.in/yaml.v3"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
var omType = g.InitOmType
|
||||
var log = g.G.LOG
|
||||
|
||||
func INIT() *config.AgentServerInfo {
|
||||
|
||||
// 获取系统的环境变量
|
||||
agentServerInfo := parseAgentServerInfo()
|
||||
|
||||
nacosConfig := g.G.NacosConfig
|
||||
|
||||
initToServerProp := &rabbitmq.ConnectProperty{
|
||||
ExchangeName: nacosConfig.GetString("octopus.message.init_exchange"),
|
||||
QueueName: nacosConfig.GetString("octopus.message.init_to_server"),
|
||||
ExchangeType: g.QueueDirect,
|
||||
TopicKey: nacosConfig.GetString("octopus.message.init_to_server_key"),
|
||||
}
|
||||
|
||||
initFromServerProp := &rabbitmq.ConnectProperty{
|
||||
ExchangeName: nacosConfig.GetString("octopus.message.init_exchange"),
|
||||
QueueName: nacosConfig.GetString("octopus.message.init_from_server"),
|
||||
ExchangeType: g.QueueDirect,
|
||||
TopicKey: nacosConfig.GetString("octopus.message.init_from_server_key"),
|
||||
}
|
||||
|
||||
// 建立RabbitMQ的连接
|
||||
// defer 关闭初始化连接
|
||||
initToServer, err := rabbitmq.NewRabbitMQConn(
|
||||
initToServerProp,
|
||||
)
|
||||
if err != nil {
|
||||
log.Error("init to server queue established error!")
|
||||
panic(err)
|
||||
}
|
||||
//defer rabbitmq.CloseChannel(initToServer)
|
||||
//defer rabbitmq.CloseChannel(initFromServer)
|
||||
|
||||
// 组装OctopusMessage
|
||||
var octopusMsg *config.OctopusMessage
|
||||
octopusMsg = octopusMsg.BuildOctopusMsg(
|
||||
omType,
|
||||
agentServerInfo,
|
||||
)
|
||||
|
||||
msgBytes, err := json.Marshal(octopusMsg)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("octopus message convert to json is wrong! msg is => %v", octopusMsg))
|
||||
}
|
||||
|
||||
log.Debug(fmt.Sprintf("Prepare to send init message to server! ==> %s", string(msgBytes)))
|
||||
|
||||
// 发送OM至MQ中
|
||||
rabbitmq.Send(
|
||||
initToServer,
|
||||
initToServerProp,
|
||||
msgBytes,
|
||||
)
|
||||
|
||||
// 监听初始化连接中的信息
|
||||
initFromServer, err := rabbitmq.NewRabbitMQConn(
|
||||
initFromServerProp,
|
||||
)
|
||||
if err != nil {
|
||||
log.Error("init from server queue established error!")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 建立运行时RabbitMQ连接
|
||||
handleInitMsgFromServer(initFromServer, initFromServerProp, initToServer, initToServerProp, agentServerInfo)
|
||||
|
||||
return agentServerInfo
|
||||
}
|
||||
|
||||
// handleInitMsgFromServer 处理从Server接收的注册信息
|
||||
func handleInitMsgFromServer(initFromServer *rabbitmq.RabbitMQConn, initFromServerProp *rabbitmq.ConnectProperty, initToServer *rabbitmq.RabbitMQConn, initToServerProp *rabbitmq.ConnectProperty, agentServerInfo *config.AgentServerInfo) {
|
||||
|
||||
deliveries := rabbitmq.Read(initFromServer, initFromServerProp, false)
|
||||
|
||||
forever := make(chan bool)
|
||||
|
||||
go func() {
|
||||
|
||||
// 同步很多抢占注册的情况
|
||||
for delivery := range deliveries {
|
||||
|
||||
log.Debug(fmt.Sprintf("message received from server is %s", string(delivery.Body)))
|
||||
|
||||
var om *config.OctopusMessage
|
||||
err := json.Unmarshal(delivery.Body, &om)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("parse init message from server wroong, message is => %s ",
|
||||
string(delivery.Body)))
|
||||
}
|
||||
|
||||
var serverInfo config.AgentServerInfo
|
||||
|
||||
s, _ := om.Content.(string)
|
||||
cc := json.Unmarshal([]byte(s), &serverInfo)
|
||||
if cc != nil {
|
||||
log.Error(fmt.Sprintf("parse init message from server wroong, message is => %v ", cc))
|
||||
}
|
||||
|
||||
serverName := serverInfo.ServerName
|
||||
|
||||
// 处理OM信息
|
||||
if om != nil && om.Type == g.InitOmType && serverName == agentServerInfo.ServerName {
|
||||
// 是本机的注册回复信息
|
||||
|
||||
// 建立运行时RabbitMQ连接
|
||||
// change to async
|
||||
go rabbitmq.HandleOMsg(om)
|
||||
|
||||
// 手动确认信息
|
||||
delivery.Ack(false)
|
||||
|
||||
// 手动关闭 注册队列的连接
|
||||
shutdownRegisterQueueConnection(initFromServer, initFromServerProp, initToServer, initToServerProp)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 不是自身的 注册回复信息 -- 拒绝
|
||||
log.Warn(fmt.Sprintf("OctopusMessage INIT from server not this agent ! => %v, ==>%s", om, delivery.Body))
|
||||
delivery.Nack(false, true)
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
// wait forever
|
||||
<-forever
|
||||
|
||||
}
|
||||
|
||||
// shutdownRegisterQueueConnection 关闭初始化连接的两个队列
|
||||
func shutdownRegisterQueueConnection(initFromServer *rabbitmq.RabbitMQConn, initFromServerProp *rabbitmq.ConnectProperty, initToServer *rabbitmq.RabbitMQConn, initToServerProp *rabbitmq.ConnectProperty) {
|
||||
|
||||
}
|
||||
|
||||
func parseAgentServerInfo() *config.AgentServerInfo {
|
||||
|
||||
// 约定文件地址为 /etc/environment.d/octopus-agent.conf
|
||||
// 目前使用
|
||||
var agentServerInfo *config.AgentServerInfo
|
||||
yamlFile, err := ioutil.ReadFile("C:\\Users\\wdd\\IdeaProjects\\ProjectOctopus\\agent-go\\server-env.yaml")
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to read YAML file: %v", err))
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(yamlFile, &agentServerInfo)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("failed to unmarshal YAML: %v", err))
|
||||
}
|
||||
|
||||
jsonFormat, err := json.Marshal(agentServerInfo)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("agent server info convert error ! agentserverinfo is %v", agentServerInfo))
|
||||
panic(err)
|
||||
}
|
||||
log.Info(fmt.Sprintf("agent server info is %v", string(jsonFormat)))
|
||||
|
||||
return agentServerInfo
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package config
|
||||
package register
|
||||
|
||||
type AgentServerInfo struct {
|
||||
ServerName string `json:"serverName" yaml:"serverName"`
|
||||
@@ -22,5 +22,5 @@ type AgentServerInfo struct {
|
||||
Comment string `json:"comment" yaml:"comment"`
|
||||
MachineID string `json:"machineId" yaml:"machineId"`
|
||||
AgentVersion string `json:"agentVersion" yaml:"agentVersion"`
|
||||
AgentTopicName string `json:"agentTopicName" yaml:"agentTopicName"`
|
||||
TopicName string `json:"topicName" yaml:"topicName"`
|
||||
}
|
||||
34
agent-go/register/ConfigParser.go
Normal file
34
agent-go/register/ConfigParser.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package register
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func ParseConfiguration(configFileName string) *viper.Viper {
|
||||
|
||||
agentConfig := parseAgentConfigFile(configFileName, nil)
|
||||
|
||||
return agentConfig
|
||||
}
|
||||
|
||||
func parseAgentConfigFile(configFileName string, v *viper.Viper) *viper.Viper {
|
||||
|
||||
// 使用Viper框架读取
|
||||
if v == nil {
|
||||
v = viper.New()
|
||||
}
|
||||
|
||||
// 设置配置文件路径和名称
|
||||
v.SetConfigName(configFileName)
|
||||
v.AddConfigPath(".")
|
||||
v.SetConfigType("yaml")
|
||||
|
||||
// 读取默认的总配置文件
|
||||
err := v.ReadInConfig()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("fatal error config file: %s", err))
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
172
agent-go/register/NacosInitalizationDeprecated.go
Normal file
172
agent-go/register/NacosInitalizationDeprecated.go
Normal file
@@ -0,0 +1,172 @@
|
||||
package register
|
||||
|
||||
//
|
||||
//import (
|
||||
// "bytes"
|
||||
// "fmt"
|
||||
// "github.com/nacos-group/nacos-sdk-go/v2/clients"
|
||||
// "github.com/nacos-group/nacos-sdk-go/v2/clients/config_client"
|
||||
// "github.com/nacos-group/nacos-sdk-go/v2/common/constant"
|
||||
// "github.com/nacos-group/nacos-sdk-go/v2/vo"
|
||||
// "github.com/spf13/viper"
|
||||
// "go.uber.org/zap"
|
||||
// "strconv"
|
||||
// "strings"
|
||||
//)
|
||||
//
|
||||
//var group = ""
|
||||
//
|
||||
//func InitNacos(configFileName string) *viper.Viper {
|
||||
//
|
||||
// v := parseAgentConfigFile(configFileName, nil)
|
||||
// group = v.GetString("spring.cloud.nacos.config.group")
|
||||
//
|
||||
// // build the nacos connection
|
||||
// configClient := startNacosConnection(v)
|
||||
//
|
||||
// // get all needed nacos config and merge
|
||||
// allNacosConfig := getAllNacosConfig(v, group, configClient)
|
||||
//
|
||||
// for _, nacosConfigContent := range allNacosConfig {
|
||||
// log.Debug(fmt.Sprintf("nacos config conetent is %s", nacosConfigContent))
|
||||
//
|
||||
// parseNacosConfigContend(nacosConfigContent, v)
|
||||
// }
|
||||
//
|
||||
// log.Info(fmt.Sprintf("%s config read result are %v", configFileName, v.AllSettings()))
|
||||
//
|
||||
// return v
|
||||
//}
|
||||
//
|
||||
//func parseAgentConfigFile(configFileName string, v *viper.Viper) *viper.Viper {
|
||||
//
|
||||
// // 使用Viper框架读取
|
||||
// if v == nil {
|
||||
// v = viper.New()
|
||||
// }
|
||||
//
|
||||
// // 设置配置文件路径和名称
|
||||
// v.SetConfigName(configFileName)
|
||||
// v.AddConfigPath(".")
|
||||
// v.SetConfigType("yaml")
|
||||
//
|
||||
// // 读取默认的总配置文件
|
||||
// err := v.ReadInConfig()
|
||||
// if err != nil {
|
||||
// panic(fmt.Errorf("fatal error config file: %s", err))
|
||||
// }
|
||||
//
|
||||
// return v
|
||||
//}
|
||||
//
|
||||
//func parseNacosConfigContend(configContent string, v *viper.Viper) *viper.Viper {
|
||||
//
|
||||
// v.SetConfigType("yaml")
|
||||
//
|
||||
// // use merge
|
||||
//
|
||||
// err := v.MergeConfig(bytes.NewBuffer([]byte(configContent)))
|
||||
// if err != nil {
|
||||
// log.Error("nacos config contend read error !", zap.Error(err))
|
||||
// }
|
||||
//
|
||||
// return v
|
||||
//}
|
||||
//func startNacosConnection(v *viper.Viper) config_client.IConfigClient {
|
||||
//
|
||||
// serverAddr := v.GetString("spring.cloud.nacos.config.server-addr")
|
||||
//
|
||||
// clientConfig := constant.ClientConfig{
|
||||
// //Endpoint: serverAddr,
|
||||
// NamespaceId: "",
|
||||
// TimeoutMs: v.GetUint64("spring.cloud.nacos.config.timeout"),
|
||||
// NotLoadCacheAtStart: true,
|
||||
// AppendToStdout: true,
|
||||
// UpdateCacheWhenEmpty: true,
|
||||
// //LogDir: "/tmp/nacos/log",
|
||||
// //CacheDir: "/tmp/nacos/cache",
|
||||
// Username: "nacos",
|
||||
// Password: "Superwmm.23",
|
||||
// }
|
||||
//
|
||||
// split := strings.Split(serverAddr, ":")
|
||||
// if len(split) != 2 {
|
||||
// log.Error("nacos server addr error!")
|
||||
// }
|
||||
//
|
||||
// port, _ := strconv.ParseUint(split[1], 10, 64)
|
||||
// serverConfigs := []constant.ServerConfig{
|
||||
// {
|
||||
// IpAddr: split[0],
|
||||
// Port: port,
|
||||
// GrpcPort: port + 1000,
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// // Another way of create config client for dynamic configuration (recommend)
|
||||
// configClient, err := clients.NewConfigClient(
|
||||
// vo.NacosClientParam{
|
||||
// ClientConfig: &clientConfig,
|
||||
// ServerConfigs: serverConfigs,
|
||||
// },
|
||||
// )
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
//
|
||||
// return configClient
|
||||
//}
|
||||
//
|
||||
//func getAllNacosConfig(v *viper.Viper, group string, configClient config_client.IConfigClient) []string {
|
||||
//
|
||||
// result := make([]string, 0)
|
||||
//
|
||||
// // main nacos configs
|
||||
// mainNacosConfigFileName := v.GetString("spring.application.name") + "-" + v.GetString("spring.profiles.active") + "." + v.GetString("spring.cloud.nacos.config.file-extension")
|
||||
//
|
||||
// log.Debug(fmt.Sprintf("main nacos config file name is %s", mainNacosConfigFileName))
|
||||
// configContent := getConfig(mainNacosConfigFileName, group, configClient)
|
||||
// result = append(result, configContent)
|
||||
//
|
||||
// // additional nacos config
|
||||
// additionalNacosConfig := v.Get("spring.cloud.nacos.config.extension-configs")
|
||||
// // 增加断言,判定map的类型
|
||||
// m, ok := additionalNacosConfig.([]interface{})
|
||||
// if !ok {
|
||||
// fmt.Println("additionalNacosConfig is not a slice")
|
||||
// return nil
|
||||
// }
|
||||
//
|
||||
// for _, addConfigMap := range m {
|
||||
//
|
||||
// realMap, _ := addConfigMap.(map[string]interface{})
|
||||
//
|
||||
// // 拿到配置的Key
|
||||
// dataId := realMap["data-id"].(string)
|
||||
// group := realMap["group"].(string)
|
||||
//
|
||||
// // 查询
|
||||
// config := getConfig(dataId, group, configClient)
|
||||
// result = append(result, config)
|
||||
// }
|
||||
//
|
||||
// return result
|
||||
//}
|
||||
//
|
||||
//// getConfig 从Nacos中获取相应的
|
||||
//func getConfig(dataId string, group string, configClient config_client.IConfigClient) string {
|
||||
//
|
||||
// log.Debug(fmt.Sprintf("nacos config get method dataID is %s, group is %s", dataId, group))
|
||||
//
|
||||
// content, err := configClient.GetConfig(vo.ConfigParam{
|
||||
// DataId: dataId,
|
||||
// Group: group,
|
||||
// })
|
||||
// if err != nil {
|
||||
// log.Error("nacos config get error !", zap.Error(err))
|
||||
// }
|
||||
//
|
||||
// log.Debug(fmt.Sprintf("dataId %s , group %s, nacos config content is %s", dataId, group, content))
|
||||
//
|
||||
// return content
|
||||
//}
|
||||
@@ -1,4 +1,4 @@
|
||||
serverName: "Chengdu-amd64-98"
|
||||
serverName: "Chengdu-amd64-90"
|
||||
serverIpPbV4: "183.220.149.17"
|
||||
serverIpInV4: ""
|
||||
serverIpPbV6: ""
|
||||
@@ -17,6 +17,6 @@ osKernelInfo: "5.4.0-135-generic"
|
||||
tcpControl: "cubic"
|
||||
virtualization: "Dedicated"
|
||||
ioSpeed: "150 MB/s"
|
||||
machineId: ""
|
||||
machineId: "fakemachinid123"
|
||||
agentVersion: ""
|
||||
agentTopicName: ""
|
||||
topicName: ""
|
||||
|
||||
50
agent-go/status/CPU.go
Normal file
50
agent-go/status/CPU.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"github.com/shirou/gopsutil/v3/cpu"
|
||||
"github.com/shirou/gopsutil/v3/load"
|
||||
)
|
||||
|
||||
type CPUStatus struct {
|
||||
NumCores int
|
||||
CPUInfo []cpu.InfoStat
|
||||
CPUPercent float64
|
||||
CPULoads *load.AvgStat
|
||||
SystemLoads *load.AvgStat
|
||||
}
|
||||
|
||||
func GetCPUStatus() (*CPUStatus, error) {
|
||||
numCores, err := cpu.Counts(true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cpuInfo, err := cpu.Info()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cpuPercent, err := cpu.Percent(0, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cpuLoads, err := load.Avg()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
systemLoads, err := load.Avg()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &CPUStatus{
|
||||
NumCores: numCores,
|
||||
CPUInfo: cpuInfo,
|
||||
CPUPercent: cpuPercent[0],
|
||||
CPULoads: cpuLoads,
|
||||
SystemLoads: systemLoads,
|
||||
}, nil
|
||||
|
||||
}
|
||||
22
agent-go/status/CPU_test.go
Normal file
22
agent-go/status/CPU_test.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetCPUStatus(t *testing.T) {
|
||||
cpuStatus, err := GetCPUStatus()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
marshalIndent, err := json.MarshalIndent(cpuStatus, "", " ")
|
||||
if err != nil {
|
||||
fmt.Printf("error")
|
||||
}
|
||||
|
||||
fmt.Println(string(marshalIndent))
|
||||
|
||||
}
|
||||
48
agent-go/status/Disk.go
Normal file
48
agent-go/status/Disk.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
type DiskStatus struct {
|
||||
Total uint64
|
||||
Used uint64
|
||||
LogicalDisk []disk.PartitionStat
|
||||
}
|
||||
|
||||
func GetDiskStatus() *DiskStatus {
|
||||
|
||||
ds := &DiskStatus{}
|
||||
|
||||
// Get disk usage
|
||||
du, _ := disk.Usage("/")
|
||||
ds.Total = du.Total
|
||||
ds.Used = du.Used
|
||||
|
||||
// Get logical disk info for Linux systems
|
||||
if runtime.GOOS == "linux" {
|
||||
ld, _ := disk.Partitions(true)
|
||||
ds.LogicalDisk = ld
|
||||
}
|
||||
|
||||
return ds
|
||||
}
|
||||
|
||||
func CalculateDiskIO() {
|
||||
|
||||
// Get initial disk IO counters
|
||||
counters1, _ := disk.IOCounters()
|
||||
time.Sleep(time.Second)
|
||||
// Get disk IO counters after 1 second
|
||||
counters2, _ := disk.IOCounters()
|
||||
|
||||
for device, counter1 := range counters1 {
|
||||
counter2 := counters2[device]
|
||||
readSpeed := float64(counter2.ReadBytes-counter1.ReadBytes) / 1024
|
||||
writeSpeed := float64(counter2.WriteBytes-counter1.WriteBytes) / 1024
|
||||
fmt.Printf("%v: read %vKB/s, write %vKB/s\n", device, readSpeed, writeSpeed)
|
||||
}
|
||||
}
|
||||
22
agent-go/status/Disk_test.go
Normal file
22
agent-go/status/Disk_test.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetDiskStatus(t *testing.T) {
|
||||
|
||||
ds := GetDiskStatus()
|
||||
fmt.Printf("Total: %v, Used: %v\n", ds.Total, ds.Used)
|
||||
fmt.Printf("Logical Disks: %v\n", ds.LogicalDisk)
|
||||
|
||||
marshalIndent, err := json.MarshalIndent(ds, "", " ")
|
||||
if err != nil {
|
||||
fmt.Printf("error")
|
||||
}
|
||||
|
||||
fmt.Println(string(marshalIndent))
|
||||
|
||||
}
|
||||
44
agent-go/status/Memory.go
Normal file
44
agent-go/status/Memory.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/shirou/gopsutil/v3/mem"
|
||||
)
|
||||
|
||||
type MemoryStatus struct {
|
||||
TotalMemory uint64
|
||||
UsedMemory uint64
|
||||
AvailableMemory uint64
|
||||
TotalVirtualMemory uint64
|
||||
UsedVirtualMemory uint64
|
||||
}
|
||||
|
||||
func GetMemoryStatus() (*MemoryStatus, error) {
|
||||
memoryStatus := &MemoryStatus{}
|
||||
|
||||
virtualMemoryStat, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
return memoryStatus, err
|
||||
}
|
||||
|
||||
memoryStatus.TotalMemory = virtualMemoryStat.Total
|
||||
memoryStatus.UsedMemory = virtualMemoryStat.Used
|
||||
memoryStatus.AvailableMemory = virtualMemoryStat.Available
|
||||
memoryStatus.TotalVirtualMemory = virtualMemoryStat.Total
|
||||
memoryStatus.UsedVirtualMemory = virtualMemoryStat.Used
|
||||
|
||||
return memoryStatus, nil
|
||||
}
|
||||
|
||||
func FormatMemorySize(size uint64) string {
|
||||
const unit = 1024
|
||||
if size < unit {
|
||||
return fmt.Sprintf("%d B", size)
|
||||
}
|
||||
div, exp := int64(unit), 0
|
||||
for n := size / unit; n >= unit; n /= unit {
|
||||
div *= unit
|
||||
exp++
|
||||
}
|
||||
return fmt.Sprintf("%.1f %cB", float64(size)/float64(div), "KMGTPE"[exp])
|
||||
}
|
||||
28
agent-go/status/Memory_test.go
Normal file
28
agent-go/status/Memory_test.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetMemoryStatus(t *testing.T) {
|
||||
|
||||
memoryStatus, err := GetMemoryStatus()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("Total Memory: %s\n", FormatMemorySize(memoryStatus.TotalMemory))
|
||||
fmt.Printf("Used Memory: %s\n", FormatMemorySize(memoryStatus.UsedMemory))
|
||||
fmt.Printf("Available Memory: %s\n", FormatMemorySize(memoryStatus.AvailableMemory))
|
||||
fmt.Printf("Total Virtual Memory: %s\n", FormatMemorySize(memoryStatus.TotalVirtualMemory))
|
||||
fmt.Printf("Used Virtual Memory: %s\n", FormatMemorySize(memoryStatus.UsedVirtualMemory))
|
||||
|
||||
marshalIndent, err := json.MarshalIndent(memoryStatus, "", " ")
|
||||
if err != nil {
|
||||
fmt.Printf("error")
|
||||
}
|
||||
|
||||
fmt.Println(string(marshalIndent))
|
||||
}
|
||||
122
agent-go/status/Network.go
Normal file
122
agent-go/status/Network.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/shirou/gopsutil/v3/net"
|
||||
net2 "net"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type NetworkStatus struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
InternalIPv4 []string `json:"internal_ip_v4,omitempty"`
|
||||
InternalIPv6 []string `json:"internal_ip_v6,omitempty"`
|
||||
ExternalIPv4 []string `json:"external_ip_v4,omitempty"`
|
||||
ExternalIPv6 []string `json:"external_ip_v6,omitempty"`
|
||||
Mac string `json:"mac,omitempty"`
|
||||
Sent uint64 `json:"sent,omitempty"`
|
||||
Recv uint64 `json:"recv,omitempty"`
|
||||
SentRate string `json:"sent_rate,omitempty"`
|
||||
RecvRate string `json:"recv_rate,omitempty"`
|
||||
}
|
||||
|
||||
func GetNetworkStatus() (*NetworkStatus, error) {
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var mainInterface net.InterfaceStat
|
||||
for _, intf := range interfaces {
|
||||
if strings.HasPrefix(intf.Name, "ens") || strings.HasPrefix(intf.Name, "eth") || strings.HasPrefix(intf.Name, "eno") {
|
||||
mainInterface = intf
|
||||
break
|
||||
}
|
||||
}
|
||||
var allAddrs []string
|
||||
log.DebugF("all main interface address are %v", mainInterface.Addrs)
|
||||
for _, addr := range mainInterface.Addrs {
|
||||
allAddrs = append(allAddrs, addr.Addr)
|
||||
}
|
||||
ipv4List, ipv6List := GetInternelIpAddrs(allAddrs)
|
||||
log.DebugF("ipv4 list are => %v, ipv6 list are => %v", ipv4List, ipv6List)
|
||||
|
||||
counters, err := net.IOCounters(true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var sent uint64
|
||||
var recv uint64
|
||||
for _, counter := range counters {
|
||||
if counter.Name == mainInterface.Name {
|
||||
sent = counter.BytesSent
|
||||
recv = counter.BytesRecv
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 休眠3秒
|
||||
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
var sentAfter uint64
|
||||
var recvAfter uint64
|
||||
countersAfter, err := net.IOCounters(true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, counter := range countersAfter {
|
||||
if counter.Name == mainInterface.Name {
|
||||
sentAfter = counter.BytesSent
|
||||
recvAfter = counter.BytesRecv
|
||||
break
|
||||
}
|
||||
}
|
||||
sendRate := fmt.Sprintf(formatBytes((sentAfter-sent)/3) + "/s")
|
||||
recvRate := fmt.Sprintf(formatBytes((recvAfter-recv)/3) + "/s")
|
||||
|
||||
info := &NetworkStatus{
|
||||
Name: mainInterface.Name,
|
||||
InternalIPv4: ipv4List,
|
||||
InternalIPv6: ipv6List,
|
||||
ExternalIPv4: nil,
|
||||
ExternalIPv6: nil,
|
||||
Mac: mainInterface.HardwareAddr,
|
||||
Sent: sent,
|
||||
Recv: recv,
|
||||
SentRate: sendRate,
|
||||
RecvRate: recvRate,
|
||||
}
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func formatBytes(bytes uint64) string {
|
||||
const unit = 1024
|
||||
if bytes < unit {
|
||||
return fmt.Sprintf("%d B", bytes)
|
||||
}
|
||||
div, exp := int64(unit), 0
|
||||
for n := bytes / unit; n >= unit; n /= unit {
|
||||
div *= unit
|
||||
exp++
|
||||
}
|
||||
return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), "KMGTPE"[exp])
|
||||
}
|
||||
|
||||
func GetInternelIpAddrs(addresses []string) ([]string, []string) {
|
||||
var ipv4 []string
|
||||
var ipv6 []string
|
||||
for _, addr := range addresses {
|
||||
// it parse (0.0.0.0) not cidr
|
||||
ip, _, err := net2.ParseCIDR(addr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if ip.To4() != nil {
|
||||
ipv4 = append(ipv4, addr)
|
||||
} else if ip.To16() != nil {
|
||||
ipv6 = append(ipv6, addr)
|
||||
}
|
||||
}
|
||||
return ipv4, ipv6
|
||||
}
|
||||
22
agent-go/status/Network_test.go
Normal file
22
agent-go/status/Network_test.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetNetworkInfo(t *testing.T) {
|
||||
|
||||
networkInfo, err := GetNetworkStatus()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
marshalIndent, err := json.MarshalIndent(networkInfo, "", " ")
|
||||
if err != nil {
|
||||
fmt.Printf("error")
|
||||
}
|
||||
|
||||
fmt.Println(string(marshalIndent))
|
||||
}
|
||||
63
agent-go/status/Status.go
Normal file
63
agent-go/status/Status.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
logger2 "agent-go/logger"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
var log = logger2.Log
|
||||
|
||||
type StatusMessage struct {
|
||||
/**
|
||||
* which kind of status should be return
|
||||
"PING";
|
||||
* METRIC => short time message
|
||||
* ALL => all agent status message
|
||||
* */
|
||||
StatusType string `json:"statusType,omitempty"`
|
||||
MetricRepeatCount int `json:"metricRepeatCount,omitempty"`
|
||||
metricRepeatPinch int `json:"metricRepeatPinch,omitempty"`
|
||||
}
|
||||
|
||||
type AgentStatus struct {
|
||||
CPUStatus *CPUStatus
|
||||
MemoryStatus *MemoryStatus
|
||||
NetworkStatus *NetworkStatus
|
||||
DiskStatus *DiskStatus
|
||||
}
|
||||
|
||||
func ConvertToFormat(eventData float64) string {
|
||||
duration := time.Duration(eventData) * time.Second
|
||||
|
||||
fmt.Println(duration)
|
||||
|
||||
hours := int(duration.Hours())
|
||||
minutes := int(duration.Minutes()) % 60
|
||||
seconds := int(duration.Seconds()) % 60
|
||||
milliseconds := duration.Milliseconds() % 1000
|
||||
return fmt.Sprintf("%02d:%02d:%02d,%03d", hours, minutes, seconds, milliseconds)
|
||||
}
|
||||
|
||||
func Ping() string {
|
||||
return "PONG"
|
||||
}
|
||||
|
||||
func ReportAppStatus() *AgentStatus {
|
||||
|
||||
cpuStatus, cpuerr := GetCPUStatus()
|
||||
memoryStatus, memerr := GetMemoryStatus()
|
||||
networkStatus, neterr := GetNetworkStatus()
|
||||
if cpuerr != nil || memerr != nil || neterr != nil {
|
||||
log.ErrorF("获取Agent的状态出现错误! 请检查")
|
||||
return nil
|
||||
}
|
||||
diskStatus := GetDiskStatus()
|
||||
return &AgentStatus{
|
||||
CPUStatus: cpuStatus,
|
||||
MemoryStatus: memoryStatus,
|
||||
NetworkStatus: networkStatus,
|
||||
DiskStatus: diskStatus,
|
||||
}
|
||||
|
||||
}
|
||||
26
agent-go/status/Status_test.go
Normal file
26
agent-go/status/Status_test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package status
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConvertToFormat(t *testing.T) {
|
||||
|
||||
convertToFormat := ConvertToFormat(99.92)
|
||||
|
||||
fmt.Println(convertToFormat)
|
||||
}
|
||||
|
||||
func TestReportAppStatus(t *testing.T) {
|
||||
|
||||
agentStatus := ReportAppStatus()
|
||||
|
||||
marshal, err := json.Marshal(agentStatus)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf(string(marshal))
|
||||
}
|
||||
7
agent-go/tmp/1.sh
Normal file
7
agent-go/tmp/1.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
|
||||
export http_proxy=http://10.250.0.10:10810 && export https_proxy=http://10.250.0.10:10810
|
||||
|
||||
|
||||
8
agent-go/tmp/executor-om-multiline.json
Normal file
8
agent-go/tmp/executor-om-multiline.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"uuid": "2023-03-27 14:38:49",
|
||||
"init_time": "2023-03-27T14:38:49.8162801+08:00",
|
||||
"type": "EXECUTOR",
|
||||
"content": "{\n \"needResultReplay\": true,\n \"durationTask,default:false\": false,\n \"type\": \"pipeline\",\n \"singleLineCommand\": null,\n \"multiLineCommand\": [[\"ls\",\"-l\"],[\"pwd\"]],\n \"pipeLineCommand\": null,\n \"resultKey\": \"output\"\n}",
|
||||
"result": "",
|
||||
"ac_time": "0001-01-01T00:00:00Z"
|
||||
}
|
||||
9
agent-go/tmp/executor-om-pipeline.json
Normal file
9
agent-go/tmp/executor-om-pipeline.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"uuid": "2023-03-27 14:38:49",
|
||||
"init_time": "2023-03-27T14:38:49.8162801+08:00",
|
||||
"type": "EXECUTOR",
|
||||
"content": "{\n \"needResultReplay\": true,\n \"durationTask,default:false\": false,\n \"type\": \"pipeline\",\n \"singleLineCommand\": null,\n \"multiLineCommand\": null,\n \"pipeLineCommand\": [[\"ls\",\"-la\"],[\"grep\", \"dev\"],[\"awk\",\"{print $9}\"]],\n \"resultKey\": \"output\"\n}\n",
|
||||
"result": "",
|
||||
"ac_time": "0001-01-01T00:00:00Z"
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"uuid": "2023-03-27 14:38:49",
|
||||
"init_time": "2023-03-27T14:38:49.8162801+08:00",
|
||||
"type": "EXECUTOR",
|
||||
"content": "{\n \"needResultReplay\": true,\n \"durationTask,default:false\": false,\n \"type\": \"command\",\n \"singleLineCommand\": [\n \"ls\",\n \"-la\"\n ],\n \"multiLineCommand\": null,\n \"pipeLineCommand\": null,\n \"resultKey\": \"output\"\n}\n",
|
||||
"content": "{\n \"needResultReplay\": true,\n \"durationTask,default:false\": false,\n \"type\": \"command\",\n \"singleLineCommand\": [\n \"ls\",\n \"-l\"\n ],\n \"multiLineCommand\": null,\n \"pipeLineCommand\": null,\n \"resultKey\": \"output\"\n}\n",
|
||||
"result": "",
|
||||
"ac_time": "0001-01-01T00:00:00Z"
|
||||
}
|
||||
|
||||
5
agent-go/tmp/init-from-server-message.json
Normal file
5
agent-go/tmp/init-from-server-message.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"uuid\":\"Chengdu-amd64-98-fakema\",\"init_time\":\"2023-06-19 15:21:02\",\"type\":\"INIT\",\"content\":\"{\\\"serverName\\\":\\\"Chengdu-amd64-98\\\",\\\"serverIpPbV4\\\":\\\"183.220.149.17\\\",\\\"serverIpInV4\\\":\\\"\\\",\\\"serverIpPbV6\\\":\\\"\\\",\\\"serverIpInV6\\\":\\\"\\\",\\\"registerTime\\\":null,\\\"expireTime\\\":null,\\\"createTime\\\":null,\\\"updateTime\\\":null,\\\"proxyType\\\":null,\\\"location\\\":\\\"Chengdu Sichuan CN\\\",\\\"provider\\\":\\\"AS139080 The Internet Data Center of Sichuan Mobile Communication Company Limited\\\",\\\"managePort\\
|
||||
\
|
||||
":\\\"22\\\",\\\"cpuBrand\\\":\\\"Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz\\\",\\\"cpuCore\\\":\\\"12 @ 4299.998 MHz\\\",\\\"memoryTotal\\\":\\\"7.6 GB\\\",\\\"diskTotal\\\":\\\"914.9 GB\\\",\\\"diskUsage\\\":\\\"12.3 GB\\\",\\\"ioSpeed\\\":\\\"150 MB/s\\\",\\\"tcpControl\\\":\\\"cubic\\\",\\\"virtualization\\\":\\\"Dedicated\\\",\\\"osInfo\\\":\\\"Ubuntu 20.04.5 LTS\\\",\\\"osKernelInfo\\\":\\\"5.4.0-135-generic\\\",\\\"machineId\\\":\\\"fakemachinid123\\\",\\\"topicName\\\":\\\"Chengdu-amd64-98-fakema\\\",\\\"comment\\\":\\\"\\\",\\\"agentVersion\\\":\\\"\\\"}\",\"result\":null,\"ac_time\":null}"
|
||||
}
|
||||
8
agent-go/tmp/init-to-server-message.json
Normal file
8
agent-go/tmp/init-to-server-message.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"uuid": "2023-06-19 14:29:20",
|
||||
"init_time": "2023-06-19 14:29:20",
|
||||
"type": "INIT",
|
||||
"content": "{\"serverName\":\"Chengdu-amd64-98\",\"serverIpPbV4\":\"183.220.149.17\",\"serverIpInV4\":\"\",\"serverIpPbV6\":\"\",\"serverIpInV6\":\"\",\"location\":\"Chengdu Sichuan CN\",\"provider\":\"AS139080 The Internet Data Center of Sichuan Mobile Communication Company Limited\",\"managePort\":\"22\",\"cpuCore\":\"12 @ 4299.998 MHz\",\"cpuBrand\":\"Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz\",\"osInfo\":\"Ubuntu 20.04.5 LTS\",\"osKernelInfo\":\"5.4.0-135-generic\",\"tcpControl\":\"cubic\",\"virtualization\":\"Dedicated\",\"ioSpeed\":\"150 MB/s\",\"memoryTotal\":\"7.6 GB\",\"diskTotal\":\"914.9 GB\",\"diskUsage\":\"12.3 GB\",\"comment\":\"\",\"machineId\":\"\",\"agentVersion\":\"\",\"agentTopicName\":\"\"}",
|
||||
"result": null,
|
||||
"ac_time": "2023-06-19 14:29:20"
|
||||
}
|
||||
BIN
agent-go/tmp/nacos_config_export_20230330143045.zip
Normal file
BIN
agent-go/tmp/nacos_config_export_20230330143045.zip
Normal file
Binary file not shown.
1
agent-go/tmp/rapid-api.sh
Normal file
1
agent-go/tmp/rapid-api.sh
Normal file
@@ -0,0 +1 @@
|
||||
92a968c0d5msh36a70a2da667c96p1bcc99jsnae97d91732f3
|
||||
7
agent-go/tmp/simple.sh
Executable file
7
agent-go/tmp/simple.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
for i in {1..30}
|
||||
do
|
||||
echo "yes"
|
||||
sleep 0.3
|
||||
done
|
||||
8
agent-go/tmp/status-agentStatus.json
Normal file
8
agent-go/tmp/status-agentStatus.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"uuid": "2023-03-27 14:38:49",
|
||||
"init_time": "2023-03-27T14:38:49.8162801+08:00",
|
||||
"type": "STATUS",
|
||||
"content": "{\n\"type\": \"status\",\n\"agent_topic_name\": \"exampleAgentTopicName\",\n\"metric_repeat_count\": 0,\n\"metric_repeat_pinch\": 0\n}",
|
||||
"result": "",
|
||||
"ac_time": "0001-01-01T00:00:00Z"
|
||||
}
|
||||
8
agent-go/tmp/status-ping.json
Normal file
8
agent-go/tmp/status-ping.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"uuid": "2023-03-27 14:38:49",
|
||||
"init_time": "2023-03-27T14:38:49.8162801+08:00",
|
||||
"type": "STATUS",
|
||||
"content": "{\n\"type\": \"ping\",\n\"agent_topic_name\": \"exampleAgentTopicName\",\n\"metric_repeat_count\": 0,\n\"metric_repeat_pinch\": 0\n}",
|
||||
"result": "",
|
||||
"ac_time": "0001-01-01T00:00:00Z"
|
||||
}
|
||||
@@ -4,13 +4,18 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// CurTimeString 输出系统时间的格式为"2006-01-02 15:04:05"形式的时间字符串
|
||||
func CurTimeString() string {
|
||||
// ParseDateTimeTime 输出系统时间的格式为"2006-01-02 15:04:05"形式的时间字符串
|
||||
func ParseDateTimeTime() string {
|
||||
|
||||
now := time.Now()
|
||||
|
||||
/*loc := time.FixedZone("UTC+8", 8*60*60) // 创建东八区时区对象
|
||||
localTime := now.In(loc) // 转换为东八区时间*/
|
||||
|
||||
return now.Format("2006-01-02 15:04:05")
|
||||
return now.Format(time.DateTime)
|
||||
}
|
||||
|
||||
func ParseISOLocalDateTime() string {
|
||||
now := time.Now()
|
||||
return now.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,15 @@ public class OMHandlerExecutor extends AbstractOctopusMessageHandler {
|
||||
@Override
|
||||
public boolean handle(OctopusMessage octopusMessage) {
|
||||
|
||||
|
||||
|
||||
if (!octopusMessage
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.getType()
|
||||
.equals(OctopusMessageType.EXECUTOR)) {
|
||||
return next.handle(octopusMessage);
|
||||
@@ -41,6 +49,7 @@ public class OMHandlerExecutor extends AbstractOctopusMessageHandler {
|
||||
try {
|
||||
|
||||
// 需要首先解析成 ExecutionMessage
|
||||
|
||||
ExecutionMessage executionMessage = objectMapper.readValue(
|
||||
(String) octopusMessage.getContent(),
|
||||
new TypeReference<ExecutionMessage>() {
|
||||
|
||||
5
agent/src/test/java/io/wdd/agent/CommandTest.java
Normal file
5
agent/src/test/java/io/wdd/agent/CommandTest.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package io.wdd.agent;
|
||||
|
||||
|
||||
public class CommandTest {
|
||||
}
|
||||
@@ -27,6 +27,10 @@
|
||||
<artifactId>oshi-core-java11</artifactId>
|
||||
<version>6.4.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package io.wdd.common;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
//import org.springframework.boot.SpringApplication;
|
||||
//import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class CommonApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(CommonApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
//@SpringBootApplication
|
||||
//public class CommonApplication {
|
||||
//
|
||||
// public static void main(String[] args) {
|
||||
// SpringApplication.run(CommonApplication.class, args);
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
package io.wdd.common.beans.status;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@SuperBuilder(toBuilder = true)
|
||||
public class OctopusStatusMessage {
|
||||
|
||||
// below two will be used by both server and agent
|
||||
// 存储所有Agent的实时健康状态, 1代表健康 0代表失败
|
||||
public static final String ALL_AGENT_STATUS_REDIS_KEY = "ALL_AGENT_HEALTHY_STATUS";
|
||||
public static final String HEALTHY_STATUS_MESSAGE_TYPE = "ping";
|
||||
public static final String ALL_STATUS_MESSAGE_TYPE = "all";
|
||||
public static final String METRIC_STATUS_MESSAGE_TYPE = "metric";
|
||||
public static final String APP_STATUS_MESSAGE_TYPE = "app";
|
||||
|
||||
/**
|
||||
* which kind of status should be return
|
||||
* metric => short time message
|
||||
* all => all agent status message
|
||||
* healthy => check for healthy
|
||||
* */
|
||||
String type;
|
||||
|
||||
String agentTopicName;
|
||||
|
||||
int metricRepeatCount;
|
||||
|
||||
int metricRepeatPinch;
|
||||
|
||||
}
|
||||
138
pom.xml
138
pom.xml
@@ -20,10 +20,10 @@
|
||||
<description>ProjectOctopus</description>
|
||||
|
||||
<modules>
|
||||
<module>agent</module>
|
||||
<module>server</module>
|
||||
<!--<module>agent</module>
|
||||
<module>common</module>
|
||||
<module>source</module>
|
||||
<module>source</module>-->
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
@@ -36,101 +36,6 @@
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>-->
|
||||
|
||||
<!-- spring cloud -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<!-- spring cloud alibaba dependency -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||
<version>${alibaba-cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||
<version>3.1.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
<version>${alibaba-cloud.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-quartz</artifactId>
|
||||
</dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.shell</groupId>
|
||||
<artifactId>spring-shell-starter</artifactId>
|
||||
</dependency>-->
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>31.1-jre</version>
|
||||
</dependency>
|
||||
|
||||
<!-- rabbitmq dependency -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- redis dependency -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<!--<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson-spring-boot-starter</artifactId>
|
||||
<version>3.13.6</version>
|
||||
</dependency>-->
|
||||
<!-- lettuce pool 缓存连接池-->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<version>1.9.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -139,11 +44,42 @@
|
||||
<optional>true</optional>
|
||||
</dependency>-->
|
||||
|
||||
<dependency>
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>-->
|
||||
|
||||
<!-- spring cloud -->
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>-->
|
||||
<!-- spring cloud alibaba dependency -->
|
||||
<!--<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
|
||||
<version>${alibaba-cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>-->
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-bootstrap</artifactId>
|
||||
<version>3.1.5</version>
|
||||
</dependency>-->
|
||||
<!--<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
|
||||
<version>${alibaba-cloud.version}</version>
|
||||
</dependency>-->
|
||||
|
||||
<!--<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-quartz</artifactId>
|
||||
</dependency>-->
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -21,9 +21,37 @@
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.wdd</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- rabbitmq dependency -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- redis dependency -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<!--<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson-spring-boot-starter</artifactId>
|
||||
<version>3.13.6</version>
|
||||
</dependency>-->
|
||||
<!-- lettuce pool 缓存连接池-->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<version>1.9.4</version>
|
||||
</dependency>
|
||||
|
||||
<!-- add in 2023-02-08 needed for some operation -->
|
||||
@@ -67,12 +95,32 @@
|
||||
<version>3.5.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
|
||||
<!--<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.1.19</version>
|
||||
</dependency>-->
|
||||
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.12.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.oshi</groupId>
|
||||
<artifactId>oshi-core-java11</artifactId>
|
||||
<version>6.4.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>31.1-jre</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
|
||||
<dependency>
|
||||
@@ -87,6 +135,12 @@
|
||||
<scope>runtime</scope>
|
||||
</dependency>-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
@MapperScan("io.wdd.server.mapper")
|
||||
public class ServerApplication {
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ServerApplication.class, args);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.wdd.common.handler;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import io.wdd.common.beans.response.R;
|
||||
import io.wdd.common.beans.response.ResultStat;
|
||||
import io.wdd.common.response.R;
|
||||
import io.wdd.common.response.ResultStat;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.amqp.rabbit.support.ListenerExecutionFailedException;
|
||||
@@ -1,6 +1,6 @@
|
||||
package io.wdd.common.handler;
|
||||
|
||||
import io.wdd.common.beans.response.ResultStat;
|
||||
import io.wdd.common.response.ResultStat;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wdd.common.beans.response;
|
||||
package io.wdd.common.response;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wdd.common.beans.response;
|
||||
package io.wdd.common.response;
|
||||
|
||||
public enum ResultStat {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.wdd.common.utils;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.wdd.common.beans.rabbitmq.OctopusMessage;
|
||||
import io.wdd.common.handler.MyRuntimeException;
|
||||
import io.wdd.rpc.message.OctopusMessage;
|
||||
import org.springframework.amqp.core.Message;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -1,12 +1,15 @@
|
||||
package io.wdd.common.utils;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
@@ -14,6 +17,16 @@ import java.time.format.DateTimeFormatter;
|
||||
@Configuration
|
||||
public class OctopusObjectMapperConfig {
|
||||
|
||||
public static ObjectMapper OctopusObjectMapper = null;
|
||||
|
||||
@Resource
|
||||
ObjectMapper objectMapper;
|
||||
|
||||
@PostConstruct
|
||||
public void setOctopusObjectMapper() {
|
||||
OctopusObjectMapper = objectMapper;
|
||||
}
|
||||
|
||||
public static Jackson2ObjectMapperBuilderCustomizer common() {
|
||||
|
||||
return jacksonObjectMapperBuilder -> {
|
||||
@@ -8,7 +8,6 @@ import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.text.SimpleDateFormat;
|
||||
@@ -7,7 +7,7 @@ import com.amazonaws.services.s3.model.S3Object;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.wdd.common.beans.response.R;
|
||||
import io.wdd.common.response.R;
|
||||
import io.wdd.func.oss.config.OctopusObjectSummary;
|
||||
import io.wdd.func.oss.config.OssConfig;
|
||||
import io.wdd.func.oss.service.OSSCoreService;
|
||||
|
||||
@@ -4,7 +4,7 @@ package io.wdd.func.controller;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.wdd.common.beans.response.R;
|
||||
import io.wdd.common.response.R;
|
||||
import io.wdd.func.xray.beans.node.ProxyNode;
|
||||
import io.wdd.func.xray.beans.node.XrayConfigInfo;
|
||||
import io.wdd.func.xray.service.XrayCallAgent;
|
||||
|
||||
@@ -3,7 +3,7 @@ package io.wdd.func.xray.service;
|
||||
import io.wdd.common.utils.TimeUtils;
|
||||
import io.wdd.func.oss.config.OctopusObjectSummary;
|
||||
import io.wdd.func.xray.beans.node.ProxyNode;
|
||||
import io.wdd.rpc.execute.service.AsyncExecutionService;
|
||||
import io.wdd.rpc.execute.service.SyncExecutionService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -83,7 +83,7 @@ public class XrayCallAgent {
|
||||
}
|
||||
|
||||
@Resource
|
||||
AsyncExecutionService executionService;
|
||||
SyncExecutionService executionService;
|
||||
|
||||
/**
|
||||
* 为代理链的每一个节点 构建Xray配置更新命令,然后发送至对应的Agent中
|
||||
@@ -131,7 +131,7 @@ public class XrayCallAgent {
|
||||
);
|
||||
|
||||
// 向Agent发送命令,执行更新操作!
|
||||
String resultKey = executionService.SendCommandToAgent(
|
||||
String resultKey = executionService.SyncSendCommandToAgent(
|
||||
proxyNode.getAgentTopicName(),
|
||||
updateCommandType,
|
||||
null,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wdd.common.beans.agent;
|
||||
package io.wdd.rpc.agent;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.AllArgsConstructor;
|
||||
@@ -1,4 +1,4 @@
|
||||
package io.wdd.common.beans.agent;
|
||||
package io.wdd.rpc.agent;
|
||||
|
||||
public enum AgentOperationType {
|
||||
|
||||
@@ -3,13 +3,11 @@ package io.wdd.rpc.agent;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.wdd.common.beans.agent.AgentOperationMessage;
|
||||
import io.wdd.common.beans.agent.AgentOperationType;
|
||||
import io.wdd.common.beans.rabbitmq.OctopusMessage;
|
||||
import io.wdd.common.beans.rabbitmq.OctopusMessageType;
|
||||
import io.wdd.common.utils.TimeUtils;
|
||||
import io.wdd.rpc.message.handler.AsyncWaitOMResult;
|
||||
import io.wdd.rpc.message.handler.OMReplayContend;
|
||||
import io.wdd.rpc.message.OctopusMessage;
|
||||
import io.wdd.rpc.message.OctopusMessageType;
|
||||
import io.wdd.rpc.message.handler.async.AsyncWaitOctopusMessageResultService;
|
||||
import io.wdd.rpc.message.handler.async.OctopusMessageAsyncReplayContend;
|
||||
import io.wdd.rpc.message.sender.OMessageToAgentSender;
|
||||
import io.wdd.server.beans.vo.ServerInfoVO;
|
||||
import io.wdd.server.config.ServerCommonPool;
|
||||
@@ -28,10 +26,10 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.wdd.rpc.init.ServerCacheAgentStatus.ALL_AGENT_TOPIC_NAME_SET;
|
||||
import static io.wdd.rpc.init.ServerCacheAgentStatus.ALL_HEALTHY_AGENT_TOPIC_NAME_LIST;
|
||||
import static io.wdd.rpc.message.handler.OMessageHandlerServer.AGENT_LATEST_VERSION;
|
||||
import static io.wdd.rpc.message.handler.OMessageHandlerServer.OCTOPUS_MESSAGE_FROM_AGENT;
|
||||
import static io.wdd.rpc.init.AgentStatusCacheService.ALL_AGENT_TOPIC_NAME_SET;
|
||||
import static io.wdd.rpc.init.AgentStatusCacheService.ALL_HEALTHY_AGENT_TOPIC_NAME_LIST;
|
||||
import static io.wdd.rpc.message.handler.sync.OMessageHandlerServer.AGENT_LATEST_VERSION;
|
||||
import static io.wdd.rpc.message.handler.sync.OMessageHandlerServer.OCTOPUS_MESSAGE_FROM_AGENT;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@@ -47,7 +45,7 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
||||
RedisTemplate redisTemplate;
|
||||
|
||||
@Resource
|
||||
AsyncWaitOMResult asyncWaitOMResult;
|
||||
AsyncWaitOctopusMessageResultService asyncWaitOctopusMessageResultService;
|
||||
|
||||
@Override
|
||||
public Map<String, String> getAllAgentVersion() {
|
||||
@@ -72,17 +70,17 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
||||
);
|
||||
|
||||
// 构造 异步结果监听内容
|
||||
OMReplayContend omReplayContend = OMReplayContend.build(
|
||||
OctopusMessageAsyncReplayContend agentReplayContend = OctopusMessageAsyncReplayContend.build(
|
||||
ALL_HEALTHY_AGENT_TOPIC_NAME_LIST.size(),
|
||||
CurrentAppOctopusMessageType,
|
||||
currentTime
|
||||
);
|
||||
|
||||
CountDownLatch countDownLatch = omReplayContend.getCountDownLatch();
|
||||
CountDownLatch countDownLatch = agentReplayContend.getCountDownLatch();
|
||||
|
||||
|
||||
// 调用后台接收处理所有的Replay信息
|
||||
asyncWaitOMResult.waitFor(omReplayContend);
|
||||
asyncWaitOctopusMessageResultService.waitFor(agentReplayContend);
|
||||
|
||||
//此处存在重大bug,会导致CPU占用飙升
|
||||
/*CompletableFuture<Void> getAllAgentVersionInfoFuture = waitCollectAllAgentVersionInfo(
|
||||
@@ -108,10 +106,10 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
||||
}
|
||||
|
||||
// 此处调用,即可中断 异步任务的收集工作
|
||||
asyncWaitOMResult.stopWaiting(omReplayContend);
|
||||
asyncWaitOctopusMessageResultService.stopWaiting(agentReplayContend);
|
||||
|
||||
// 处理结果
|
||||
omReplayContend
|
||||
agentReplayContend
|
||||
.getReplayOMList()
|
||||
.stream()
|
||||
.forEach(
|
||||
@@ -124,7 +122,7 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
||||
);
|
||||
|
||||
// help gc
|
||||
omReplayContend = null;
|
||||
agentReplayContend = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -158,16 +156,16 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
||||
);
|
||||
|
||||
// 构造结果
|
||||
OMReplayContend omReplayContend = OMReplayContend.build(
|
||||
OctopusMessageAsyncReplayContend OctopusMessageAsyncReplayContend = io.wdd.rpc.message.handler.async.OctopusMessageAsyncReplayContend.build(
|
||||
ALL_HEALTHY_AGENT_TOPIC_NAME_LIST.size(),
|
||||
CurrentAppOctopusMessageType,
|
||||
currentTime
|
||||
);
|
||||
|
||||
CountDownLatch countDownLatch = omReplayContend.getCountDownLatch();
|
||||
CountDownLatch countDownLatch = OctopusMessageAsyncReplayContend.getCountDownLatch();
|
||||
|
||||
// 调用后台接收处理所有的Replay信息
|
||||
asyncWaitOMResult.waitFor(omReplayContend);
|
||||
asyncWaitOctopusMessageResultService.waitFor(OctopusMessageAsyncReplayContend);
|
||||
|
||||
/* CompletableFuture<Void> getAllAgentCoreInfoFuture = waitCollectAllAgentCoreInfo(
|
||||
result,
|
||||
@@ -187,10 +185,10 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
||||
// 超时,或者 全部信息已经收集
|
||||
|
||||
// 此处调用,即可中断 异步任务的收集工作
|
||||
asyncWaitOMResult.stopWaiting(omReplayContend);
|
||||
asyncWaitOctopusMessageResultService.stopWaiting(OctopusMessageAsyncReplayContend);
|
||||
|
||||
// 处理结果
|
||||
omReplayContend
|
||||
OctopusMessageAsyncReplayContend
|
||||
.getReplayOMList()
|
||||
.stream()
|
||||
.forEach(
|
||||
@@ -218,7 +216,7 @@ public class OctopusAgentServiceImpl implements OctopusAgentService {
|
||||
);
|
||||
|
||||
// help gc
|
||||
omReplayContend = null;
|
||||
OctopusMessageAsyncReplayContend = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.wdd.rpc.controller;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.wdd.common.beans.response.R;
|
||||
import io.wdd.common.response.R;
|
||||
import io.wdd.rpc.agent.OctopusAgentService;
|
||||
import io.wdd.server.beans.vo.ServerInfoVO;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user