diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml
index cdc0aa42843..75a8fc5c6fe 100644
--- a/.github/workflows/frontend.yml
+++ b/.github/workflows/frontend.yml
@@ -5,7 +5,7 @@ name: Frontend CI
on:
push:
- branches: [master]
+ branches: ["*"]
paths:
- "src/frontend/**"
pull_request:
diff --git a/README.md b/README.md
index c79e7dca228..08afad6fb6a 100644
--- a/README.md
+++ b/README.md
@@ -59,6 +59,8 @@ bk-ci提供了流水线、代码检查、代码库、凭证管理、环境管理
- [BK-JOB](https://github.com/Tencent/bk-job):蓝鲸作业平台(Job)是一套运维脚本管理系统,具备海量任务并发处理能力。
- [BK-PaaS](https://github.com/Tencent/bk-PaaS):蓝鲸PaaS平台是一个开放式的开发平台,让开发者可以方便快捷地创建、开发、部署和管理SaaS应用。
- [BK-SOPS](https://github.com/Tencent/bk-sops):蓝鲸标准运维(SOPS)是通过可视化的图形界面进行任务流程编排和执行的系统,是蓝鲸体系中一款轻量级的调度编排类SaaS产品。
+- [BK-Repo](https://github.com/Tencentblueking/bk-repo):蓝鲸制品库平台是一套为企业提供各种类型制品包存储、代理、分发、晋级、扫描、依赖包管理的持续交付平台。
+- [BK-Turbo](https://github.com/Tencentblueking/bk-turbo): 蓝鲸编译加速平台为CI场景下提供UE、C/C++等多种语言的编译加速服务能力
## Contributing
- 关于 bk-ci 分支管理、issue 以及 pr 规范,请阅读 [Contributing](CONTRIBUTING.md)
diff --git a/README_EN.md b/README_EN.md
index 6d6b0727b05..05e05a0b02e 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -61,7 +61,9 @@ bk-ci provides seven core services, namely Process, CodeCheck, Repository, Ticke
- [BK-CMDB](https://github.com/Tencent/bk-cmdb): BlueKing Configuration Management DataBase (BlueKing CMDB) is an enterprise level configuration management platform for assets and applications.
- [BK-JOB](https://github.com/Tencent/bk-job): BlueKing JOB is a set of operation and maintenance script management platform with the ability to handle a large number of tasks concurrently.
- [BK-PaaS](https://github.com/Tencent/bk-PaaS): BlueKing PaaS is an open development platform that allows developers to create, develop, deploy and manage SaaS applications quickly and easily.
+- [BK-Repo](https://github.com/Tencentblueking/bk-repo): The BlueKing Artifact Repository Platform is a continuous delivery platform that provides enterprises with various types of artifact package storage, proxy, distribution, promotion, scanning, and dependency package management.
- [BK-SOPS](https://github.com/Tencent/bk-sops): BlueKing Standard OPS (SOPS) is a light-weighted SaaS product in the Tencent BlueKing product system designed for the orchestration and execution of tasks through a graphical interface.
+- [BK-Turbo](https://github.com/Tencentblueking/bk-turbo): The BlueKing Turbo Platform provides compilation acceleration services for various languages, including UE and C/C++, in CI scenarios.
## Contributing
- Please read [Contributing](CONTRIBUTING.en.md) for the branch management, issue and pr specifications of bk-ci.
diff --git a/docs/overview/db/data_clear.md b/docs/overview/db/data_clear.md
new file mode 100644
index 00000000000..96c63b9905b
--- /dev/null
+++ b/docs/overview/db/data_clear.md
@@ -0,0 +1,141 @@
+# 蓝盾数据清理
+## 背景
+
+ 随着蓝盾的构建量快速增长, 蓝盾DB的数据量也越来越大,而蓝盾的DB的容量是有限的,故蓝盾需要一套DB数据清理方案来保证系统的稳定。
+
+
+
+## 清理步骤
+
+#### 一、确定表数据清理方案
+
+ 蓝盾的表可以分为流水数据表和非流水线数据表这二种类型,流水数据表很早之前的数据用户并不关心,所以流水线数库表可以通过分区表的方式来定时清理数据;非流水线数据表的数据相对比较重要,没法简单按时间维度删除数据,故我们需要开发一个依据特定条件删除数据的定时任务。
+
+
+
+#### 二、分区表数据清理
+
+##### 1、确定数据库表是否能调整为分区表
+
+**新增表:** 新表没有历史包袱,只需明确分区的字段和每个分区的大小就行,以下是按时间就行分区表的建表语句:
+
+```
+CREATE TABLE `T_REPOSITORY_COMMIT` (
+ `ID` bigint(20) NOT NULL AUTO_INCREMENT,
+ `BUILD_ID` varchar(34) DEFAULT NULL,
+ `PIPELINE_ID` varchar(34) DEFAULT NULL,
+ `REPO_ID` bigint(20) DEFAULT NULL,
+ `TYPE` smallint(6) DEFAULT NULL COMMENT '1-svn, 2-git, 3-gitlab',
+ `COMMIT` varchar(64) DEFAULT NULL,
+ `COMMITTER` varchar(64) DEFAULT NULL,
+ `COMMIT_TIME` datetime DEFAULT NULL,
+ `COMMENT` longtext /*!99104 COMPRESSED */,
+ `ELEMENT_ID` varchar(34) DEFAULT NULL,
+ `REPO_NAME` varchar(128) DEFAULT NULL,
+ `CREATE_TIME` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `URL` varchar(255) DEFAULT NULL COMMENT '代码库URL',
+ PRIMARY KEY (`ID`,`CREATE_TIME`),
+ KEY `BUILD_ID_INDEX` (`BUILD_ID`),
+ KEY `IDX_PIPE_ELEMENT_REPO_TIME` (`PIPELINE_ID`,`ELEMENT_ID`,`REPO_ID`,`COMMIT_TIME`),
+ KEY `IDX_BUILD_ID_TIME` (`BUILD_ID`,`COMMIT_TIME`),
+ KEY `IDX_PIPE_ELEMENT_NAME_REPO_TIME` (`PIPELINE_ID`,`ELEMENT_ID`,`REPO_NAME`,`COMMIT_TIME`)
+) ENGINE=InnoDB AUTO_INCREMENT=3170191500 DEFAULT CHARSET=utf8mb4
+/*!50100 PARTITION BY RANGE (TO_DAYS(CREATE_TIME))
+(PARTITION p20240424 VALUES LESS THAN (739366) ENGINE = InnoDB,
+ PARTITION p20240501 VALUES LESS THAN (739373) ENGINE = InnoDB,
+ PARTITION p20240508 VALUES LESS THAN (739380) ENGINE = InnoDB,
+ PARTITION p20240515 VALUES LESS THAN (739387) ENGINE = InnoDB,
+ PARTITION p20240522 VALUES LESS THAN (739394) ENGINE = InnoDB,
+ PARTITION p20240529 VALUES LESS THAN (739401) ENGINE = InnoDB,
+ PARTITION p20240605 VALUES LESS THAN (739408) ENGINE = InnoDB,
+ PARTITION p20240612 VALUES LESS THAN (739415) ENGINE = InnoDB,
+ PARTITION p20240619 VALUES LESS THAN (739422) ENGINE = InnoDB,
+ PARTITION p20240626 VALUES LESS THAN (739429) ENGINE = InnoDB,
+ PARTITION p20240703 VALUES LESS THAN (739436) ENGINE = InnoDB,
+ PARTITION p20240710 VALUES LESS THAN (739443) ENGINE = InnoDB,
+ PARTITION p20240717 VALUES LESS THAN (739450) ENGINE = InnoDB,
+ PARTITION p20240724 VALUES LESS THAN (739457) ENGINE = InnoDB,
+ PARTITION p20240731 VALUES LESS THAN (739464) ENGINE = InnoDB,
+ PARTITION p20240807 VALUES LESS THAN (739471) ENGINE = InnoDB,
+ PARTITION p20240814 VALUES LESS THAN (739478) ENGINE = InnoDB,
+ PARTITION p20240821 VALUES LESS THAN (739485) ENGINE = InnoDB,
+ PARTITION p20240828 VALUES LESS THAN (739492) ENGINE = InnoDB) */;
+```
+
+**存量表:** 存量表要在不影响现有业务的情况下调整为分区表相对比较麻烦点,以T_REPOSITORY_COMMIT表为例,以下是具体步骤:
+
+1、创建临时表T_REPOSITORY_COMMIT_TMP(必须为分区表,分区键必须包含在主键内)
+
+2、把T_REPOSITORY_COMMIT表的数据同步至T_REPOSITORY_COMMIT_TMP表并建立同步方案
+
+3、执行 RENAME TABLE T_REPOSITORY_COMMIT TO T_REPOSITORY_COMMIT_BAK,T_REPOSITORY_COMMIT_TMP TO T_REPOSITORY_COMMIT ,T_REPOSITORY_COMMIT_BAK TO T_REPOSITORY_COMMIT_TMP; 该语句进行新旧表名互换。
+
+4、删除T_REPOSITORY_COMMIT_TMP表
+
+
+
+##### 2、为分区表创立自动创建分区和删除分区的执行计划
+
+
+
+**各微服务数据库的分区表情况:**
+
+| 数据库名称 | 表名 | 分区字段 | 过期时间(单位:天) | 分区间隔(单位:天) |
+| ----------------- | ----------------------------------- | --------------- | -------------------- | -------------------- |
+| devops_process | T_PIPELINE_TRIGGER_EVENT | CREATE_TIME | 35 | 7 |
+| devops_process | T_PIPELINE_TRIGGER_DETAIL | CREATE_TIME | 35 | 7 |
+| devops_process | T_PIPELINE_BUILD_VAR | CREATE_TIME | 42 | 7 |
+| devops_process | T_PIPELINE_BUILD_TASK | CREATE_TIME | 42 | 7 |
+| devops_process | T_PIPELINE_BUILD_STAGE | CREATE_TIME | 42 | 7 |
+| devops_process | T_PIPELINE_BUILD_CONTAINER | CREATE_TIME | 42 | 7 |
+| devops_process | T_PROJECT_PIPELINE_CALLBACK_HISTORY | CREATE_TIME | 3 | 3 |
+| devops_process | T_PIPELINE_WEBHOOK_BUILD_LOG | CREATE_TIME | 3 | 3 |
+| devops_process | T_PIPELINE_WEBHOOK_BUILD_LOG_DETAIL | CREATE_TIME | 3 | 3 |
+| devops_repository | T_REPOSITORY_COMMIT | CREATE_TIME | 35 | 7 |
+| devops_repository | T_REPOSITORY_WEBHOOK_REQUEST | CREATE_TIME | 35 | 7 |
+| devops_notify | T_NOTIFY_WEWORK | CREATED_TIME | 8 | 1 |
+| devops_notify | T_NOTIFY_EMAIL | CREATED_TIME | 8 | 1 |
+| devops_notify | T_NOTIFY_RTX | CREATED_TIME | 8 | 1 |
+| devops_notify | T_NOTIFY_SMS | CREATED_TIME | 8 | 1 |
+| devops_notify | T_NOTIFY_WECHAT | CREATED_TIME | 8 | 1 |
+| devops_plugin | T_PLUGIN_GIT_CHECK | CREATE_TIME | 31 | 1 |
+| devops_stream | T_GIT_REQUEST_EVENT_BUILD | CREATE_TIME | 35 | 7 |
+| devops_stream | T_GIT_REQUEST_REPO_EVENT | CREATE_TIME | 35 | 7 |
+| devops_stream | T_GIT_REQUEST_EVENT_NOT_BUILD | CREATE_TIME | 35 | 7 |
+| devops_stream | T_GIT_USER_MESSAGE | CREATE_TIME | 35 | 7 |
+| devops_stream | T_GIT_REQUEST_EVENT | CREATE_TIME | 35 | 7 |
+| devops_metrics | T_PROJECT_THIRD_PLATFORM_DATA | CREATE_TIME | 371 | 7 |
+| devops_metrics | T_PIPELINE_FAIL_DETAIL_DATA | CREATE_TIME | 371 | 7 |
+| devops_metrics | T_PIPELINE_FAIL_SUMMARY_DATA | CREATE_TIME | 371 | 7 |
+| devops_metrics | T_ATOM_MONITOR_DATA_DAILY | STATISTICS_TIME | 371 | 7 |
+| devops_metrics | T_ATOM_INDEX_STATISTICS_DAILY | CREATE_TIME | 371 | 7 |
+| devops_metrics | T_ATOM_FAIL_DETAIL_DATA | CREATE_TIME | 210 | 7 |
+| devops_metrics | T_PIPELINE_OVERVIEW_DATA | CREATE_TIME | 371 | 7 |
+| devops_metrics | T_ATOM_FAIL_SUMMARY_DATA | CREATE_TIME | 371 | 7 |
+| devops_metrics | T_PIPELINE_STAGE_OVERVIEW_DATA | CREATE_TIME | 371 | 7 |
+| devops_metrics | T_ATOM_OVERVIEW_DATA | CREATE_TIME | 371 | 7 |
+| devops_metrics | T_PROJECT_USER_DAILY | THE_DATE | 90 | 15 |
+| devops_metrics | T_PROJECT_BUILD_SUMMARY_DAILY | THE_DATE | 90 | 15 |
+
+
+
+#### 三、非分区表数据清理
+
+非分区表采用misc服务的定时任务依据时间、构建数量等条件进行清理,具体配置如下:
+
+```
+build:
+ data:
+ clear:
+ switch: true # 是否开启自动清理构建历史数据;true:开启,false:不开启
+ maxEveryProjectHandleNum: 5 #并发清理项目数量
+ monthRange: -1 # 清理多少个月前的普通渠道(BS)流水线运行时数据,对于卡在 stage 审核的流程在清理后就无法继续审核。
+ maxKeepNum: 10000 # 普通渠道(BS)流水线最大保留多少条构建历史记录
+ codeccDayRange: -14 # 清理多少天前的codecc渠道流水线运行时数据
+ codeccMaxKeepNum: 14 # codecc渠道流水线最大保留多少条构建历史记录
+ otherMonthRange: -1 # 清理多少天前的其它渠道流水线运行时数据
+ otherMaxKeepNum: 500 # 其它渠道流水线最大保留多少条构建历史记录
+ clearChannelCodes: "BS,PREBUILD,CI,CODECC" # 支持清理构建上数据的渠道类型
+ maxThreadHandleProjectNum: 5 # 开启清理线程最大数量
+```
+
diff --git a/docs/overview/db/devops_ci_dispatch.md b/docs/overview/db/devops_ci_dispatch.md
index 7169efe9ce8..1f54524f78c 100644
--- a/docs/overview/db/devops_ci_dispatch.md
+++ b/docs/overview/db/devops_ci_dispatch.md
@@ -438,6 +438,7 @@
| 18 | CONTAINER_HASH_ID | varchar | 128 | 0 | Y | N | | 容器 ID 日志使用 |
| 19 | ENV_ID | bigint | 20 | 0 | Y | N | | 第三方构建所属环境 |
| 20 | IGNORE_ENV_AGENT_IDS | json | 1073741824 | 0 | Y | N | | 这次调度被排除的 agent 节点 |
+| 21 | JOB_ID | varchar | 128 | 0 | Y | N | | 当前构建所属 jobid |
**表名:** T_DISPATCH_THIRDPARTY_AGENT_DOCKER_DEBUG
diff --git a/docs/overview/db/devops_ci_environment.md b/docs/overview/db/devops_ci_environment.md
index 67c04cdedcf..f6f82037fee 100644
--- a/docs/overview/db/devops_ci_environment.md
+++ b/docs/overview/db/devops_ci_environment.md
@@ -190,6 +190,7 @@
| 1 | ENV_ID | bigint | 20 | 0 | N | Y | | 环境 ID |
| 2 | NODE_ID | bigint | 20 | 0 | N | Y | | 节点 ID |
| 3 | PROJECT_ID | varchar | 64 | 0 | N | N | | 项目 ID |
+| 4 | ENABLE_NODE | bit | 1 | 0 | N | N | b'1' | 是否启用节点 |
**表名:** T_ENV_SHARE_PROJECT
diff --git a/docs/overview/db/devops_ci_log.md b/docs/overview/db/devops_ci_log.md
index 2dd08054973..2cde1010584 100644
--- a/docs/overview/db/devops_ci_log.md
+++ b/docs/overview/db/devops_ci_log.md
@@ -42,10 +42,12 @@
| 3 | TAG | varchar | 64 | 0 | Y | N | | 标签 |
| 4 | SUB_TAG | varchar | 256 | 0 | Y | N | | 子标签 |
| 5 | JOB_ID | varchar | 64 | 0 | Y | N | | JOBID |
-| 6 | MODE | varchar | 32 | 0 | Y | N | | LogStorageMode |
-| 7 | EXECUTE_COUNT | int | 10 | 0 | N | N | | 执行次数 |
-| 8 | FINISHED | bit | 1 | 0 | N | N | b'0' | buildisfinishedornot |
-| 9 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
+| 6 | USER_JOB_ID | varchar | 128 | 0 | Y | N | | 真正的 jobId,已经存在的 JOB_ID 字段其实是 containerhashid |
+| 7 | STEP_ID | varchar | 64 | 0 | Y | N | | 用户填写的插件 id |
+| 8 | MODE | varchar | 32 | 0 | Y | N | | LogStorageMode |
+| 9 | EXECUTE_COUNT | int | 10 | 0 | N | N | | 执行次数 |
+| 10 | FINISHED | bit | 1 | 0 | N | N | b'0' | buildisfinishedornot |
+| 11 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
**表名:** T_LOG_SUBTAGS
diff --git a/docs/overview/db/devops_ci_process.md b/docs/overview/db/devops_ci_process.md
index 4b7c7af266c..82aba3c8d41 100644
--- a/docs/overview/db/devops_ci_process.md
+++ b/docs/overview/db/devops_ci_process.md
@@ -211,7 +211,7 @@
| 4 | BUILD_NUM | int | 10 | 0 | Y | N | 0 | 构建次数 |
| 5 | PROJECT_ID | varchar | 64 | 0 | N | N | | 项目 ID |
| 6 | PIPELINE_ID | varchar | 34 | 0 | N | N | | 流水线 ID |
-| 7 | VERSION | int | 10 | 0 | Y | N | | 版本号 |
+| 7 | VERSION | int | 10 | 0 | Y | N | | 编排版本号 |
| 8 | START_USER | varchar | 64 | 0 | Y | N | | 启动者 |
| 9 | TRIGGER | varchar | 32 | 0 | N | N | | 触发器 |
| 10 | START_TIME | timestamp | 19 | 0 | Y | N | | 开始时间 |
@@ -241,7 +241,7 @@
| 34 | BUILD_NUM_ALIAS | varchar | 256 | 0 | Y | N | | 自定义构建号 |
| 35 | CONCURRENCY_GROUP | varchar | 255 | 0 | Y | N | | 并发时,设定的 group |
| 36 | UPDATE_TIME | datetime | 19 | 0 | Y | N | CURRENT_TIMESTAMP | 更新时间 |
-| 37 | VERSION_NAME | varchar | 64 | 0 | Y | N | | 版本名称 |
+| 37 | VERSION_NAME | varchar | 64 | 0 | Y | N | | 正式版本名称 |
| 38 | YAML_VERSION | varchar | 34 | 0 | Y | N | | YAML 的版本标记 |
**表名:** T_PIPELINE_BUILD_HISTORY_DEBUG
@@ -258,7 +258,7 @@
| 4 | BUILD_NUM | int | 10 | 0 | Y | N | 0 | 构建次数 |
| 5 | PROJECT_ID | varchar | 64 | 0 | N | N | | 项目 ID |
| 6 | PIPELINE_ID | varchar | 34 | 0 | N | N | | 流水线 ID |
-| 7 | VERSION | int | 10 | 0 | Y | N | | 版本号 |
+| 7 | VERSION | int | 10 | 0 | Y | N | | 编排版本号 |
| 8 | START_USER | varchar | 64 | 0 | Y | N | | 启动者 |
| 9 | TRIGGER | varchar | 32 | 0 | N | N | | 触发器 |
| 10 | START_TIME | timestamp | 19 | 0 | Y | N | | 开始时间 |
@@ -1265,6 +1265,7 @@
| 9 | SECRET_TOKEN | text | 65535 | 0 | Y | N | | Sendtoyourwithhttpheader:X-DEVOPS-WEBHOOK-TOKEN |
| 10 | ENABLE | bit | 1 | 0 | N | N | b'1' | 启用 |
| 11 | FAILURE_TIME | datetime | 19 | 0 | Y | N | | 失败时间 |
+| 12 | SECRET_PARAM | text | 65535 | 0 | Y | N | | 鉴权参数 |
**表名:** T_PROJECT_PIPELINE_CALLBACK_HISTORY
@@ -1399,3 +1400,4 @@
| 12 | BUILD_NO | text | 65535 | 0 | Y | N | | 构建号 |
| 13 | PARAM | mediumtext | 16777215 | 0 | Y | N | | 参数 |
| 14 | DELETED | bit | 1 | 0 | Y | N | b'0' | 流水线已被软删除 |
+| 15 | INSTANCE_ERROR_INFO | text | 65535 | 0 | Y | N | | 实例化错误信息 |
diff --git a/docs/overview/db/devops_ci_store.md b/docs/overview/db/devops_ci_store.md
index d6a308d9fde..d4065da48ff 100644
--- a/docs/overview/db/devops_ci_store.md
+++ b/docs/overview/db/devops_ci_store.md
@@ -40,8 +40,15 @@
| T_REASON | 原因定义表 |
| T_REASON_REL | 原因和组件关联关系 |
| T_STORE_APPROVE | 审核表 |
+| T_STORE_BASE | 研发商店组件基本信息表 |
+| T_STORE_BASE_ENV | 研发商店组件执行环境信息表 |
+| T_STORE_BASE_ENV_EXT | 研发商店组件执行环境信息扩展表 |
+| T_STORE_BASE_EXT | 研发商店组件基本信息扩展表 |
+| T_STORE_BASE_FEATURE | 研发商店组件特性信息表 |
+| T_STORE_BASE_FEATURE_EXT | 研发商店组件特性信息扩展表 |
| T_STORE_BUILD_APP_REL | store 构建与编译环境关联关系表 |
| T_STORE_BUILD_INFO | store 组件构建信息表 |
+| T_STORE_CATEGORY_REL | 研发商店组件与范畴关联关系表 |
| T_STORE_COMMENT | store 组件评论信息表 |
| T_STORE_COMMENT_PRAISE | store 组件评论点赞信息表 |
| T_STORE_COMMENT_REPLY | store 组件评论回复信息表 |
@@ -57,6 +64,7 @@
| T_STORE_INDEX_ELEMENT_DETAIL | 研发商店组件指标要素详情表 |
| T_STORE_INDEX_LEVEL_INFO | 研发商店指标等级信息表 |
| T_STORE_INDEX_RESULT | 研发商店组件指标结果表 |
+| T_STORE_LABEL_REL | 研发商店组件与标签关联关系表 |
| T_STORE_MEDIA_INFO | 媒体信息表 |
| T_STORE_MEMBER | store 组件成员信息表 |
| T_STORE_OPT_LOG | store 操作日志表 |
@@ -72,6 +80,7 @@
| T_STORE_STATISTICS | store 统计信息表 |
| T_STORE_STATISTICS_DAILY | store 每日统计信息表 |
| T_STORE_STATISTICS_TOTAL | store 全量统计信息表 |
+| T_STORE_VERSION_LOG | 研发商店组件版本日志表 |
| T_TEMPLATE | 模板信息表 |
| T_TEMPLATE_CATEGORY_REL | 模板与范畴关联关系表 |
| T_TEMPLATE_LABEL_REL | 模板与标签关联关系表 |
@@ -174,7 +183,7 @@
| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| 1 | ID | varchar | 32 | 0 | N | Y | | 主键 ID |
| 2 | ATOM_CODE | varchar | 64 | 0 | N | N | | 插件的唯一标识 |
-| 3 | TEST_PROJECT_CODE | varchar | 32 | 0 | N | N | | 调试项目编码 |
+| 3 | TEST_PROJECT_CODE | varchar | 64 | 0 | N | N | | 调试项目编码 |
| 4 | APPROVE_ID | varchar | 32 | 0 | N | N | | 审批 ID |
| 5 | CREATOR | varchar | 50 | 0 | N | N | system | 创建者 |
| 6 | MODIFIER | varchar | 50 | 0 | N | N | system | 最近修改人 |
@@ -703,6 +712,138 @@
| 13 | UPDATE_TIME | datetime | 19 | 0 | N | N | CURRENT_TIMESTAMP | 更新时间 |
| 14 | TOKEN | varchar | 64 | 0 | Y | N | | |
+**表名:** T_STORE_BASE
+
+**说明:** 研发商店组件基本信息表
+
+**数据列:**
+
+| 序号 | 名称 | 数据类型 | 长度 | 小数位 | 允许空值 | 主键 | 默认值 | 说明 |
+| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+| 1 | ID | varchar | 32 | 0 | N | Y | | 主键 ID |
+| 2 | STORE_CODE | varchar | 64 | 0 | N | N | | 组件唯一标识 |
+| 3 | STORE_TYPE | tinyint | 4 | 0 | N | N | 0 | store 组件类型 |
+| 4 | NAME | varchar | 64 | 0 | N | N | | 组件名称 |
+| 5 | VERSION | varchar | 256 | 0 | N | N | | 版本号 |
+| 6 | STATUS | varchar | 64 | 0 | N | N | | 状态 |
+| 7 | STATUS_MSG | varchar | 1024 | 0 | Y | N | | 状态对应的描述,如上架失败原因 |
+| 8 | DOCS_LINK | varchar | 256 | 0 | Y | N | | 说明文档链接 |
+| 9 | LOGO_URL | varchar | 256 | 0 | Y | N | | logo 地址 |
+| 10 | SUMMARY | varchar | 256 | 0 | Y | N | | 组件简介 |
+| 11 | DESCRIPTION | mediumtext | 16777215 | 0 | Y | N | | 组件描述 |
+| 12 | LATEST_FLAG | bit | 1 | 0 | N | N | | 是否为最新版本,TRUE:最新 FALSE:非最新 |
+| 13 | PUBLISHER | varchar | 1024 | 0 | N | N | system | 发布者,对应 T_STORE_PUBLISHER_INFO 表的 PUBLISHER_NAME 字段 |
+| 14 | PUB_TIME | datetime | 23 | 0 | Y | N | | 发布时间 |
+| 15 | CLASSIFY_ID | varchar | 32 | 0 | N | N | | 所属分类 ID |
+| 16 | CREATOR | varchar | 50 | 0 | N | N | system | 创建人 |
+| 17 | MODIFIER | varchar | 50 | 0 | N | N | system | 最近修改人 |
+| 18 | UPDATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 修改时间 |
+| 19 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
+
+**表名:** T_STORE_BASE_ENV
+
+**说明:** 研发商店组件执行环境信息表
+
+**数据列:**
+
+| 序号 | 名称 | 数据类型 | 长度 | 小数位 | 允许空值 | 主键 | 默认值 | 说明 |
+| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+| 1 | ID | varchar | 32 | 0 | N | Y | | 主键 |
+| 2 | STORE_ID | varchar | 32 | 0 | N | N | | 组件基本信息表 ID |
+| 3 | LANGUAGE | varchar | 64 | 0 | Y | N | | 开发语言 |
+| 4 | MIN_VERSION | varchar | 20 | 0 | Y | N | | 支持开发语言的最低版本 |
+| 5 | PKG_NAME | varchar | 256 | 0 | Y | N | | 包名称 |
+| 6 | PKG_PATH | varchar | 1024 | 0 | Y | N | | 包路径 |
+| 7 | TARGET | varchar | 256 | 0 | Y | N | | 执行入口 |
+| 8 | SHA_CONTENT | varchar | 1024 | 0 | Y | N | | SHA 签名串 |
+| 9 | PRE_CMD | text | 65535 | 0 | Y | N | | 执行前置命令 |
+| 10 | OS_NAME | varchar | 128 | 0 | Y | N | | 支持的操作系统名称 |
+| 11 | OS_ARCH | varchar | 128 | 0 | Y | N | | 支持的操作系统架构 |
+| 12 | RUNTIME_VERSION | varchar | 128 | 0 | Y | N | | 运行时版本 |
+| 13 | DEFAULT_FLAG | bit | 1 | 0 | N | N | b'1' | 是否为默认环境信息 |
+| 14 | CREATOR | varchar | 50 | 0 | N | N | system | 创建人 |
+| 15 | MODIFIER | varchar | 50 | 0 | N | N | system | 最近修改人 |
+| 16 | UPDATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 修改时间 |
+| 17 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
+
+**表名:** T_STORE_BASE_ENV_EXT
+
+**说明:** 研发商店组件执行环境信息扩展表
+
+**数据列:**
+
+| 序号 | 名称 | 数据类型 | 长度 | 小数位 | 允许空值 | 主键 | 默认值 | 说明 |
+| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+| 1 | ID | varchar | 32 | 0 | N | Y | | 主键 ID |
+| 2 | ENV_ID | varchar | 32 | 0 | N | N | | 组件执行环境信息表 ID |
+| 3 | STORE_ID | varchar | 32 | 0 | N | N | | 组件基本信息表 ID |
+| 4 | FIELD_NAME | varchar | 64 | 0 | N | N | | 字段名称 |
+| 5 | FIELD_VALUE | mediumtext | 16777215 | 0 | N | N | | 字段值 |
+| 6 | CREATOR | varchar | 50 | 0 | N | N | system | 创建人 |
+| 7 | MODIFIER | varchar | 50 | 0 | N | N | system | 最近修改人 |
+| 8 | UPDATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 修改时间 |
+| 9 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
+
+**表名:** T_STORE_BASE_EXT
+
+**说明:** 研发商店组件基本信息扩展表
+
+**数据列:**
+
+| 序号 | 名称 | 数据类型 | 长度 | 小数位 | 允许空值 | 主键 | 默认值 | 说明 |
+| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+| 1 | ID | varchar | 32 | 0 | N | Y | | 主键 ID |
+| 2 | STORE_ID | varchar | 32 | 0 | N | N | | 组件基本信息表 ID |
+| 3 | STORE_CODE | varchar | 64 | 0 | N | N | | 组件唯一标识 |
+| 4 | STORE_TYPE | tinyint | 4 | 0 | N | N | 0 | store 组件类型 |
+| 5 | FIELD_NAME | varchar | 64 | 0 | N | N | | 字段名称 |
+| 6 | FIELD_VALUE | mediumtext | 16777215 | 0 | N | N | | 字段值 |
+| 7 | CREATOR | varchar | 50 | 0 | N | N | system | 创建人 |
+| 8 | MODIFIER | varchar | 50 | 0 | N | N | system | 最近修改人 |
+| 9 | UPDATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 修改时间 |
+| 10 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
+
+**表名:** T_STORE_BASE_FEATURE
+
+**说明:** 研发商店组件特性信息表
+
+**数据列:**
+
+| 序号 | 名称 | 数据类型 | 长度 | 小数位 | 允许空值 | 主键 | 默认值 | 说明 |
+| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+| 1 | ID | varchar | 32 | 0 | N | Y | | 主键 ID |
+| 2 | STORE_CODE | varchar | 64 | 0 | N | N | | 组件唯一标识 |
+| 3 | STORE_TYPE | tinyint | 4 | 0 | N | N | 0 | store 组件类型 |
+| 4 | PUBLIC_FLAG | bit | 1 | 0 | Y | N | b'0' | 是否为公共组件,TRUE:是 FALSE:不是 |
+| 5 | RECOMMEND_FLAG | bit | 1 | 0 | Y | N | b'1' | 是否推荐,TRUE:是 FALSE:不是 |
+| 6 | CERTIFICATION_FLAG | bit | 1 | 0 | Y | N | b'0' | 是否官方认证,TRUE:是 FALSE:不是 |
+| 7 | TYPE | varchar | 32 | 0 | Y | N | | 类型 |
+| 8 | RD_TYPE | varchar | 32 | 0 | Y | N | | 研发类型 |
+| 9 | WEIGHT | int | 10 | 0 | Y | N | | 权重(数值越大代表权重越高) |
+| 10 | CREATOR | varchar | 50 | 0 | N | N | system | 创建人 |
+| 11 | MODIFIER | varchar | 50 | 0 | N | N | system | 最近修改人 |
+| 12 | UPDATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 修改时间 |
+| 13 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
+
+**表名:** T_STORE_BASE_FEATURE_EXT
+
+**说明:** 研发商店组件特性信息扩展表
+
+**数据列:**
+
+| 序号 | 名称 | 数据类型 | 长度 | 小数位 | 允许空值 | 主键 | 默认值 | 说明 |
+| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+| 1 | ID | varchar | 32 | 0 | N | Y | | 主键 ID |
+| 2 | FEATURE_ID | varchar | 32 | 0 | N | N | | 组件特性信息表 ID |
+| 3 | STORE_CODE | varchar | 64 | 0 | N | N | | 组件唯一标识 |
+| 4 | STORE_TYPE | tinyint | 4 | 0 | N | N | 0 | store 组件类型 |
+| 5 | FIELD_NAME | varchar | 64 | 0 | N | N | | 字段名称 |
+| 6 | FIELD_VALUE | text | 65535 | 0 | N | N | | 字段值 |
+| 7 | CREATOR | varchar | 50 | 0 | N | N | system | 创建人 |
+| 8 | MODIFIER | varchar | 50 | 0 | N | N | system | 最近修改人 |
+| 9 | UPDATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 修改时间 |
+| 10 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
+
**表名:** T_STORE_BUILD_APP_REL
**说明:** store 构建与编译环境关联关系表
@@ -739,6 +880,22 @@
| 10 | SAMPLE_PROJECT_PATH | varchar | 500 | 0 | N | N | | 样例工程路径 |
| 11 | STORE_TYPE | tinyint | 4 | 0 | N | N | 0 | store 组件类型 0:插件 1:模板 2:镜像 3:IDE 插件 4:微扩展 |
+**表名:** T_STORE_CATEGORY_REL
+
+**说明:** 研发商店组件与范畴关联关系表
+
+**数据列:**
+
+| 序号 | 名称 | 数据类型 | 长度 | 小数位 | 允许空值 | 主键 | 默认值 | 说明 |
+| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+| 1 | ID | varchar | 32 | 0 | N | Y | | 主键 |
+| 2 | CATEGORY_ID | varchar | 32 | 0 | N | N | | 范畴 ID |
+| 3 | STORE_ID | varchar | 32 | 0 | N | N | | 组件 ID |
+| 4 | CREATOR | varchar | 50 | 0 | N | N | system | 创建人 |
+| 5 | MODIFIER | varchar | 50 | 0 | N | N | system | 最近修改人 |
+| 6 | UPDATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 修改时间 |
+| 7 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
+
**表名:** T_STORE_COMMENT
**说明:** store 组件评论信息表
@@ -1032,6 +1189,22 @@
| 10 | UPDATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 修改时间 |
| 11 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
+**表名:** T_STORE_LABEL_REL
+
+**说明:** 研发商店组件与标签关联关系表
+
+**数据列:**
+
+| 序号 | 名称 | 数据类型 | 长度 | 小数位 | 允许空值 | 主键 | 默认值 | 说明 |
+| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+| 1 | ID | varchar | 32 | 0 | N | Y | | 主键 |
+| 2 | LABEL_ID | varchar | 32 | 0 | N | N | | 标签 ID |
+| 3 | STORE_ID | varchar | 32 | 0 | N | N | | 组件 ID |
+| 4 | CREATOR | varchar | 50 | 0 | N | N | system | 创建人 |
+| 5 | MODIFIER | varchar | 50 | 0 | N | N | system | 最近修改人 |
+| 6 | UPDATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 修改时间 |
+| 7 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
+
**表名:** T_STORE_MEDIA_INFO
**说明:** 媒体信息表
@@ -1120,6 +1293,7 @@
| 7 | UPDATE_TIME | datetime | 19 | 0 | N | N | CURRENT_TIMESTAMP | 更新时间 |
| 8 | STORE_TYPE | tinyint | 4 | 0 | N | N | 0 | 商店组件类型 0:插件 1:模板 2:镜像 3:IDE 插件 |
| 9 | BUS_TYPE | varchar | 32 | 0 | N | N | BUILD | 业务类型 BUILD:构建 INDEX:研发商店指标 |
+| 10 | PROJECT_CODE | varchar | 64 | 0 | N | N | | 项目代码 |
**表名:** T_STORE_PKG_RUN_ENV_INFO
@@ -1153,13 +1327,15 @@
| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
| 1 | ID | varchar | 32 | 0 | N | Y | | 主键 ID |
| 2 | STORE_CODE | varchar | 64 | 0 | N | N | | store 组件编码 |
-| 3 | PROJECT_CODE | varchar | 32 | 0 | N | N | | 用户组所属项目 |
+| 3 | PROJECT_CODE | varchar | 64 | 0 | N | N | | 所属项目 |
| 4 | TYPE | tinyint | 4 | 0 | N | N | | 类型 |
-| 5 | CREATOR | varchar | 50 | 0 | N | N | system | 创建者 |
-| 6 | MODIFIER | varchar | 50 | 0 | N | N | system | 修改者 |
-| 7 | CREATE_TIME | datetime | 19 | 0 | N | N | CURRENT_TIMESTAMP | 创建时间 |
-| 8 | UPDATE_TIME | datetime | 19 | 0 | N | N | CURRENT_TIMESTAMP | 更新时间 |
-| 9 | STORE_TYPE | tinyint | 4 | 0 | N | N | 0 | store 组件类型 |
+| 5 | VERSION | varchar | 256 | 0 | Y | N | | 版本号 |
+| 6 | INSTANCE_ID | varchar | 256 | 0 | Y | N | | 实例 ID |
+| 7 | CREATOR | varchar | 50 | 0 | N | N | system | 创建者 |
+| 8 | MODIFIER | varchar | 50 | 0 | N | N | system | 修改者 |
+| 9 | CREATE_TIME | datetime | 19 | 0 | N | N | CURRENT_TIMESTAMP | 创建时间 |
+| 10 | UPDATE_TIME | datetime | 19 | 0 | N | N | CURRENT_TIMESTAMP | 更新时间 |
+| 11 | STORE_TYPE | tinyint | 4 | 0 | N | N | 0 | store 组件类型 |
**表名:** T_STORE_PUBLISHER_INFO
@@ -1306,9 +1482,10 @@
| 6 | DAILY_SUCCESS_NUM | int | 10 | 0 | Y | N | 0 | 每日执行成功数 |
| 7 | DAILY_FAIL_NUM | int | 10 | 0 | Y | N | 0 | 每日执行失败总数 |
| 8 | DAILY_FAIL_DETAIL | varchar | 4096 | 0 | Y | N | | 每日执行失败详情 |
-| 9 | STATISTICS_TIME | datetime | 23 | 0 | N | N | | 统计时间 |
-| 10 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
-| 11 | UPDATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 更新时间 |
+| 9 | DAILY_ACTIVE_DURATION | decimal | 16 | 2 | Y | N | | 每日活跃时长,单位:小时 |
+| 10 | STATISTICS_TIME | datetime | 23 | 0 | N | N | | 统计时间 |
+| 11 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
+| 12 | UPDATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 更新时间 |
**表名:** T_STORE_STATISTICS_TOTAL
@@ -1327,9 +1504,27 @@
| 7 | SCORE_AVERAGE | decimal | 4 | 1 | Y | N | 0.0 | 评论均分 |
| 8 | PIPELINE_NUM | int | 10 | 0 | Y | N | 0 | 流水线数量 |
| 9 | RECENT_EXECUTE_NUM | int | 10 | 0 | Y | N | 0 | 最近执行次数 |
-| 10 | CREATE_TIME | datetime | 19 | 0 | N | N | CURRENT_TIMESTAMP | 创建时间 |
-| 11 | UPDATE_TIME | datetime | 19 | 0 | N | N | CURRENT_TIMESTAMP | 更新时间 |
-| 12 | HOT_FLAG | bit | 1 | 0 | Y | N | b'0' | 是否为受欢迎组件 |
+| 10 | RECENT_ACTIVE_DURATION | decimal | 16 | 2 | Y | N | | 总活跃时长,单位:小时 |
+| 11 | CREATE_TIME | datetime | 19 | 0 | N | N | CURRENT_TIMESTAMP | 创建时间 |
+| 12 | UPDATE_TIME | datetime | 19 | 0 | N | N | CURRENT_TIMESTAMP | 更新时间 |
+| 13 | HOT_FLAG | bit | 1 | 0 | Y | N | b'0' | 是否为受欢迎组件 |
+
+**表名:** T_STORE_VERSION_LOG
+
+**说明:** 研发商店组件版本日志表
+
+**数据列:**
+
+| 序号 | 名称 | 数据类型 | 长度 | 小数位 | 允许空值 | 主键 | 默认值 | 说明 |
+| :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
+| 1 | ID | varchar | 32 | 0 | N | Y | | 主键 |
+| 2 | STORE_ID | varchar | 32 | 0 | N | N | | 组件 ID |
+| 3 | RELEASE_TYPE | tinyint | 4 | 0 | N | N | | 发布类型,0:新上架 1:非兼容性升级 2:兼容性功能更新 3:兼容性问题修正 |
+| 4 | CONTENT | text | 65535 | 0 | N | N | | 版本日志内容 |
+| 5 | CREATOR | varchar | 50 | 0 | N | N | system | 创建人 |
+| 6 | MODIFIER | varchar | 50 | 0 | N | N | system | 最近修改人 |
+| 7 | UPDATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 修改时间 |
+| 8 | CREATE_TIME | datetime | 23 | 0 | N | N | CURRENT_TIMESTAMP(3) | 创建时间 |
**表名:** T_TEMPLATE
diff --git a/docs/overview/db/sharding_dev.md b/docs/overview/db/sharding_dev.md
new file mode 100644
index 00000000000..bdaff4d2c83
--- /dev/null
+++ b/docs/overview/db/sharding_dev.md
@@ -0,0 +1,276 @@
+# 蓝盾分库分表开发指南
+## 背景
+
+ 随着蓝盾的构建量快速增长, 快速增长的构建量带来的请求量和数据给蓝盾数据带来了巨大的压力 ,巨大的QPS量和数据量已经让单机数据库达到了瓶颈,蓝盾db支持分库分表势在必行。
+
+
+
+## 开发步骤
+
+#### 一、确定分库分表数量
+
+ 根据流水线构建趋势图确定分库分表数量,保证分库分表数量合理。
+
+
+
+#### 二、增加分库分表配置
+
+##### 1、在devops_ci_project数据库的T_DATA_SOURCE表插入分区库的记录,T_TABLE_SHARDING_CONFIG表插入分区表的记录(只分库不分表的情况下可以不用配置),数据库表的结构如下:
+
+```
+CREATE TABLE `T_DATA_SOURCE` (
+ `ID` varchar(32) NOT NULL DEFAULT '' COMMENT '主键ID',
+ `MODULE_CODE` varchar(64) NOT NULL DEFAULT '' COMMENT '模块标识',
+ `DATA_SOURCE_NAME` varchar(128) NOT NULL DEFAULT '' COMMENT '数据源名称',
+ `FULL_FLAG` bit(1) DEFAULT b'0' COMMENT '容量是否满标识 true:是,false:否',
+ `CREATOR` varchar(50) NOT NULL DEFAULT 'system' COMMENT '创建者',
+ `MODIFIER` varchar(50) NOT NULL DEFAULT 'system' COMMENT '修改者',
+ `UPDATE_TIME` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '修改时间',
+ `CREATE_TIME` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
+ `CLUSTER_NAME` varchar(64) NOT NULL DEFAULT '' COMMENT '集群名称',
+ `DS_URL` varchar(1024) DEFAULT NULL COMMENT '数据源URL地址',
+ `TAG` varchar(128) DEFAULT NULL COMMENT '数据源标签',
+ `TYPE` varchar(32) NOT NULL DEFAULT 'DB' COMMENT '数据库类型,DB:普通数据库,ARCHIVE_DB:归档数据库',
+ PRIMARY KEY (`ID`),
+ UNIQUE KEY `UNI_INX_TDS_CLUSTER_MODULE_TYPE_NAME` (`CLUSTER_NAME`,`MODULE_CODE`,`TYPE`,`DATA_SOURCE_NAME`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='模块数据源配置';
+
+sql示例:
+INSERT INTO devops_ci_project.T_DATA_SOURCE
+(ID, MODULE_CODE, DATA_SOURCE_NAME, FULL_FLAG, CREATOR, MODIFIER, UPDATE_TIME, CREATE_TIME, CLUSTER_NAME, DS_URL, TAG, `TYPE`)
+VALUES('eae3670d3716427881c93fde46e28532', 'PROCESS', 'ds_0', 0, 'system', 'system', '2022-01-11 15:42:20.280', '2022-01-11 15:42:20.280', 'prod', 'xxxxx', NULL, 'DB');
+
+INSERT INTO devops_ci_project.T_DATA_SOURCE
+(ID, MODULE_CODE, DATA_SOURCE_NAME, FULL_FLAG, CREATOR, MODIFIER, UPDATE_TIME, CREATE_TIME, CLUSTER_NAME, DS_URL, TAG, `TYPE`)
+VALUES('eae3670d3716427881c93fde46e28533', 'PROCESS', 'ds_1', 0, 'system', 'system', '2022-01-19 11:04:45.529', '2022-01-11 15:42:20.280', 'prod', 'xxxxx', NULL, 'DB');
+
+INSERT INTO devops_ci_project.T_DATA_SOURCE
+(ID, MODULE_CODE, DATA_SOURCE_NAME, FULL_FLAG, CREATOR, MODIFIER, UPDATE_TIME, CREATE_TIME, CLUSTER_NAME, DS_URL, TAG, `TYPE`)
+VALUES('eae3670d3716427881c93fde46e26537', 'PROCESS', 'archive_ds_0', 0, 'system', 'system', '2024-01-03 18:31:10.459', '2024-01-03 18:31:10.459', 'stream', 'xxxxx', 'archive', 'ARCHIVE_DB');
+
+CREATE TABLE `T_TABLE_SHARDING_CONFIG` (
+ `ID` varchar(32) NOT NULL DEFAULT '' COMMENT '主键ID',
+ `CLUSTER_NAME` varchar(64) NOT NULL DEFAULT '' COMMENT '集群名称',
+ `MODULE_CODE` varchar(64) NOT NULL DEFAULT '' COMMENT '模块标识',
+ `TABLE_NAME` varchar(128) NOT NULL DEFAULT '' COMMENT '数据库表名称',
+ `SHARDING_NUM` int(11) NOT NULL DEFAULT '5' COMMENT '分表数量',
+ `CREATOR` varchar(50) NOT NULL DEFAULT 'system' COMMENT '创建者',
+ `MODIFIER` varchar(50) NOT NULL DEFAULT 'system' COMMENT '修改者',
+ `UPDATE_TIME` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '修改时间',
+ `CREATE_TIME` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
+ PRIMARY KEY (`ID`),
+ UNIQUE KEY `UNI_INX_TTSC_CLUSTER_MODULE_NAME` (`CLUSTER_NAME`,`MODULE_CODE`,`TABLE_NAME`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='数据库表分片配置';
+```
+
+
+
+##### 2、在蓝盾对应微服务(以process为例)的yml文件增加分库分表数据源配置,模板如下(**db的序号不能随便更改,后续如果新增分区库需要往下按序号追加**):
+
+```
+spring:
+ datasource:
+ # 普通库数据源配置(勿随便变更配置项的顺序)
+ dataSourceConfigs:
+ - index: 0
+ url: jdbc:mysql://xxx01:10000/devops_ci_process?useSSL=false&autoReconnect=true&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
+ username: ENC(xxxxx)
+ password: ENC(xxxxx)
+ - index: 1
+ url: jdbc:mysql://xxx02:10000/devops_ci_process?useSSL=false&autoReconnect=true&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
+ username: ENC(xxxxx)
+ password: ENC(xxxxx)
+ # 归档库数据源配置(勿随便变更配置项的顺序)
+ archiveDataSourceConfigs:
+ - index: 0
+ url: jdbc:mysql://archivexxx01:10000/devops_ci_archive_process?useSSL=false&autoReconnect=true&serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
+ username: ENC(xxxxx)
+ password: ENC(xxxxx)
+```
+
+
+
+##### 3、在蓝盾对应微服务(以process为例)的yml文件增加公共分片规则配置
+
+```
+# shardingsphere分片规则配置
+sharding:
+ databaseShardingStrategy:
+ algorithmClassName: "com.tencent.devops.process.sharding.BkProcessDatabaseShardingAlgorithm" # 普通业务库分库路由算法实现类
+ archiveAlgorithmClassName: "com.tencent.devops.process.sharding.BkProcessArchiveDatabaseShardingAlgorithm" # 归档库分库路由算法实现类
+ shardingField: PROJECT_ID # 分库分片键
+ tableShardingStrategy:
+ archiveAlgorithmClassName: "com.tencent.devops.process.sharding.BkProcessArchiveTableShardingAlgorithm" # 归档库分表路由算法实现类
+ shardingField: PROJECT_ID # 分表分片键
+ archiveFlag: Y # 是否使用归档库标识;Y:是,N:否
+ defaultFlag: Y # 是否使用默认库标识;Y:是,N:否
+ routing:
+ cacheSize: 100000 # 缓存分片规则最大数量
+ migration:
+ timeout: 2 # 迁移项目超时时间,单位:小时
+ maxProjectCount: 5 # 同时迁移项目最大数量
+ processDbMicroServices: "process,engine,misc,lambda" #使用process数据库的微服务
+ sourceDbDataDeleteFlag: false # 迁移成功后是否删除原库数据
+ tableShardingStrategy:
+ defaultShardingNum: 1 # 默认分表数量
+```
+
+
+
+##### 4、在蓝盾对应微服务(以process为例)的yml文件增表的分片规则配置
+
+```
+spring:
+ profiles: prod
+ datasource:
+ tableRuleConfigs:
+ - index: 0 # 序号
+ name: T_AUDIT_RESOURCE # 表名
+ databaseShardingStrategy: SHARDING # 分库策略
+ tableShardingStrategy: SHARDING # 分表策略(可为空,不分表的情况下可以不配)
+ shardingNum: 1 # 分表数量(可为空,不分表的情况下可以不配)
+ - index: 1 # 序号
+ name: T_PIPELINE_RULE # 表名
+ broadcastFlag: true # 是否为广播表(所有分区库中该表的数据都一样)
+```
+
+
+
+##### 5、分布式ID配置
+
+ 蓝盾数据库表的ID分为UUID(**全局唯一**)和数据库自增长主键ID(**非全局唯一**),我们为数据库自增长主键ID的表开发了基于号段模式实现的分布式ID方案 ,该方案需在devops_ci_project数据库的T_LEAF_ALLOC表插入业务ID生成方案配置的记录 ,数据库表的结构如下:
+
+```
+CREATE TABLE `T_LEAF_ALLOC` (
+ `BIZ_TAG` varchar(128) NOT NULL DEFAULT '' COMMENT '业务标签',
+ `MAX_ID` bigint(20) NOT NULL DEFAULT '1' COMMENT '当前最大ID值',
+ `STEP` int(11) NOT NULL COMMENT '步长,每一次请求获取的ID个数',
+ `DESCRIPTION` varchar(256) DEFAULT NULL COMMENT '说明',
+ `UPDATE_TIME` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+ PRIMARY KEY (`BIZ_TAG`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='ID管理数据表';
+```
+
+
+
+##### 6、按照分表数量新建表(如果只分库不分表可以忽略该步骤)
+
+示例:T_ATOM_OVERVIEW_DATA表分表数量为2,需要新建T_ATOM_OVERVIEW_DATA(**供jooq生成数据模型,不存数据**)、T_ATOM_OVERVIEW_DATA_0、T_ATOM_OVERVIEW_DATA_1 这三张表。
+
+
+
+#### 三、业务逻辑开发
+
+1、涉及分区表的sql需加上分片键,保证sql路由到目标db或者表执行。
+
+```
+xxxxxx WHERE PROJECT_ID = "xxx"
+```
+
+
+
+2、如果业务要用数据库自增长主键ID需要 调取project服务封装的分布式ID生成接口获取ID,调用代码模板如下:
+
+```
+client.get(ServiceAllocIdResource::class).generateSegmentId(TEMPLATE_BIZ_TAG_NAME).data
+```
+
+
+
+#### 四:路由分配规则二次开发(非必须)
+
+在为项目分片路由规则的时候默认采用的是随机分配算法,如果想保证各分区库或者分区表的访问流量、数据量相对比较均衡,可以根据自身业务特点对项目的路由规则进行二次开发(列如可以计算每个分区库或者分区表一段时间的总构建量,新建项目的时候将总构建量相对较小的db或者表分配给该项目)
+
+ /**
+ * 获取可用数据源名称
+ * @param clusterName db集群名称
+ * @param moduleCode 模块代码
+ * @param ruleType 规则类型
+ * @param dataSourceNames 数据源名称集合
+ * @return 可用数据源名称
+ */
+ override fun getValidDataSourceName(
+ clusterName: String,
+ moduleCode: SystemModuleEnum,
+ ruleType: ShardingRuleTypeEnum,
+ dataSourceNames: List
+ ): String {
+ // 从可用的数据源中随机选择一个分配给该项目
+ val maxSizeIndex = dataSourceNames.size - 1
+ val randomIndex = (0..maxSizeIndex).random()
+ return dataSourceNames[randomIndex]
+ }
+
+ /**
+ * 获取可用数据库表名称
+ * @param ruleType 规则类型
+ * @param dataSourceName 数据源名称
+ * @param tableShardingConfig 分表配置
+ * @return 可用数据库表名称
+ */
+ override fun getValidTableName(
+ ruleType: ShardingRuleTypeEnum,
+ dataSourceName: String,
+ tableShardingConfig: TableShardingConfig
+ ): String {
+ // 从可用的数据库表中随机选择一个分配给该项目
+ val tableName = tableShardingConfig.tableName
+ val shardingNum = tableShardingConfig.shardingNum
+ return if (shardingNum > 1) {
+ val maxSizeIndex = shardingNum - 1
+ val randomIndex = (0..maxSizeIndex).random()
+ "${tableName}_$randomIndex"
+ } else {
+ tableName
+ }
+ }
+#####
+
+#### 五:数据迁移(非必须)
+
+在原来db的数据量比较大的情况下,我们会增加新的db组成新的db集群以实现扩容,如果想把原db的部分数据迁移到db以减轻原db的压力可以使用蓝盾迁移项目数据的接口实现,具体的步骤如下:
+
+##### 1、为新增的db配置指定tag
+
+示例:
+
+INSERT INTO devops_ci_project.T_DATA_SOURCE
+(ID, MODULE_CODE, DATA_SOURCE_NAME, FULL_FLAG, CREATOR, MODIFIER, UPDATE_TIME, CREATE_TIME, CLUSTER_NAME, DS_URL, TAG, `TYPE`)
+VALUES('eae3670d3716427881c93fde46e28501', 'PROCESS', 'ds_3', 0, 'system', 'system', '2023-08-29 15:44:40.694', '2023-08-29 15:44:40.694', 'prod', 'xxx', '**tagxxx**', 'DB');
+
+
+
+##### 2、在misc服务调用蓝盾迁移项目数据的接口
+
+```
+curl -X PUT "http://xxx/api/op/process/db/projects/{projectId}/data/migrate?cancelFlag=true&dataTag=tagxxx" -H "accept: application/json" -H "X-DEVOPS-UID: xxx"
+```
+
+参数说明:
+
+| 参数名称 | 参数类型 | 说明 |
+| ------------ | -------- | ---------------------- |
+| X-DEVOPS-UID | header | 迁移触发人 |
+| projectId | path | 迁移项目 |
+| cancelFlag | query | 是否取消正在运行的构建 |
+| dataTag | query | 迁移库对应的数据标签 |
+
+
+
+**注意:**
+
+1、迁移项目前需要向项目的负责人明确迁移时是否要取消当前正在运行的构建(**不允许取消构建可能存在迁移后数据不一致的情况**),如果允许取消:cancelFlag字段传true,不允许取消:cancelFlag字段传false。
+
+2、迁移失败后该项目的流量还是处于锁定状态,如果不继续迁移了,需要调用project微服务的项目流量解锁接口进行解锁,该接口调用示例如下:
+
+```
+curl -X PUT "http://xxx/api/op/projects/{projectId}/pipeline/build/unlock" -H "accept: application/json" -H "X-DEVOPS-UID: xxx"
+```
+
+
+
+##### 3、把新增的db配置的tag置为null
+
+把新增的db配置的tag置为null后,则说明新增db已经正式加入默认集群,为新项目创建分片路由规则时也可能会将新增的db分配给该项目使用。
+
+UPDATE devops_ci_project.T_DATA_SOURCE SET TAG = **null** WHERE ID = 'xxxxxx';
\ No newline at end of file
diff --git a/helm-charts/core/ci/Chart.lock b/helm-charts/core/ci/Chart.lock
index c769f98630d..16713a585e1 100644
--- a/helm-charts/core/ci/Chart.lock
+++ b/helm-charts/core/ci/Chart.lock
@@ -25,6 +25,6 @@ dependencies:
version: 10.30.6
- name: kubernetes-manager
repository: file://./local_chart/kubernetes-management
- version: 0.0.37
-digest: sha256:f39b897b438471cfb4cc9e98a3c4c44ec9d8950c1bb7b658dda8a354cad922a3
-generated: "2023-08-09T15:09:12.834702422+08:00"
+ version: 0.0.45
+digest: sha256:bb11b7ac0e3487504f5563cd2b170d04038fc8971aaecbaca3dc5ecdcb792a43
+generated: "2024-06-21T18:05:57.191350067+08:00"
diff --git a/helm-charts/core/ci/base/values.yaml b/helm-charts/core/ci/base/values.yaml
index 58cb936e802..0094c6c3794 100644
--- a/helm-charts/core/ci/base/values.yaml
+++ b/helm-charts/core/ci/base/values.yaml
@@ -174,7 +174,8 @@ elasticsearch:
rabbitmq:
enabled: true
image:
- repository: bkci/rabbitmq-with-delay
+ registry: docker.io/bkci
+ repository: rabbitmq-with-delay
tag: 0.0.1
persistence:
size: 10Gi
diff --git a/helm-charts/core/ci/build_chart.py b/helm-charts/core/ci/build_chart.py
index 1bfdc77e328..ddb24e417cf 100755
--- a/helm-charts/core/ci/build_chart.py
+++ b/helm-charts/core/ci/build_chart.py
@@ -78,7 +78,7 @@
else:
camelize_set.add(camelize_key)
if line.replace(key, "").strip().endswith(":"):
- line = line.replace(key, '{{ .Values.config.'+camelize_key+' | quote }}')
+ line = line.replace(key, '{{ .Values.config.'+camelize_key+' | default "" | quote }}')
else:
line = line.replace(key, '{{ .Values.config.'+camelize_key+' }}')
new_file.write(line)
@@ -106,7 +106,7 @@
gateway_config_file.write(env+": "+include_dict[camelize_key]+"\n")
else:
camelize_set.add(camelize_key)
- gateway_config_file.write(env+": "+'{{ .Values.config.'+camelize_key+" | quote }}\n")
+ gateway_config_file.write(env+": "+'{{ .Values.config.'+camelize_key+' | default "" | quote }}\n')
# 前端文件
for root, dirs, files in os.walk(frontend_path):
for frontend_file in files:
@@ -125,7 +125,7 @@
gateway_config_file.write(env+": "+include_dict[camelize_key]+"\n")
else:
camelize_set.add(camelize_key)
- gateway_config_file.write(env+": "+'{{ .Values.config.'+camelize_key+" | quote }}\n")
+ gateway_config_file.write(env+": "+'{{ .Values.config.'+camelize_key+' | default "" | quote }}\n')
gateway_config_file.write('NAMESPACE: {{ .Release.Namespace }}\n')
gateway_config_file.write('CHART_NAME: {{ include "bkci.names.fullname" . }}\n')
gateway_config_file.write('{{ end }}')
diff --git a/helm-charts/core/ci/charts/kubernetes-manager-0.0.45.tgz b/helm-charts/core/ci/charts/kubernetes-manager-0.0.45.tgz
index 92f2b7f9809..bf049c9fea9 100644
Binary files a/helm-charts/core/ci/charts/kubernetes-manager-0.0.45.tgz and b/helm-charts/core/ci/charts/kubernetes-manager-0.0.45.tgz differ
diff --git a/helm-charts/core/ci/local_chart/kubernetes-management/Chart.yaml b/helm-charts/core/ci/local_chart/kubernetes-management/Chart.yaml
index b1de242ebb1..87ba8e44885 100644
--- a/helm-charts/core/ci/local_chart/kubernetes-management/Chart.yaml
+++ b/helm-charts/core/ci/local_chart/kubernetes-management/Chart.yaml
@@ -2,7 +2,7 @@ apiVersion: v2
name: kubernetes-manager
description: A Helm chart for BlueKing CI Kubernetes Manager
type: application
-version: 0.0.37
+version: 0.0.45
appVersion: 0.0.31
home: https://github.com/Tencent/bk-ci
diff --git a/helm-charts/core/ci/local_chart/kubernetes-management/templates/deployment.yaml b/helm-charts/core/ci/local_chart/kubernetes-management/templates/deployment.yaml
index 3038bb8ebd8..26c681cde45 100644
--- a/helm-charts/core/ci/local_chart/kubernetes-management/templates/deployment.yaml
+++ b/helm-charts/core/ci/local_chart/kubernetes-management/templates/deployment.yaml
@@ -76,6 +76,14 @@ spec:
value: {{ .Values.multiCluster.enabled | quote }}
- name: DEFAULT_NAMESPACE
value: {{ .Values.multiCluster.defaultNamespace }}
+ {{- if .Values.kubernetesManager.docker.enable }}
+ - name: DOCKER_HOST
+ value: tcp://localhost:2375
+ {{- end}}
+ {{- if .Values.kubernetesManager.debug }}
+ - name: KUBERNETES_MANAGER_DEBUG_ENABLE
+ value: "true"
+ {{- end}}
workingDir: /data/workspace/kubernetes-manager
livenessProbe:
tcpSocket:
@@ -99,8 +107,22 @@ spec:
mountPath: /data/workspace/kubernetes-manager/config
readOnly: true
{{- end}}
- {{- if .Values.configmap.enabled}}
+ {{- if .Values.kubernetesManager.docker.enable }}
+ - name: kuberentes-manager-docker
+ image: {{ .Values.kubernetesManager.docker.image }}
+ command: ["dockerd", "--host", "tcp://localhost:2375"]
+ {{- if .Values.kubernetesManager.docker.resources }}
+ resources: {{- toYaml .Values.kubernetesManager.docker.resources | nindent 12 }}
+ {{- end }}
+ securityContext:
+ privileged: true
+ volumeMounts:
+ - name: docker-graph-storage
+ mountPath: /var/lib/docker
+ {{- end }}
+
volumes:
+ {{- if .Values.configmap.enabled}}
- name: kubernetes-manager-config
configMap:
name: kubernetes-manager
@@ -110,6 +132,10 @@ spec:
{{- if .Values.kubeConfig.useKubeConfig}}
- key: kubeConfig.yaml
path: kubeConfig.yaml
- {{- end}}
+ {{- end}}
+ {{- if .Values.kubernetesManager.docker.enable }}
+ - name: docker-graph-storage
+ emptyDir: {}
+ {{- end}}
{{- end}}
{{- end -}}
diff --git a/helm-charts/core/ci/local_chart/kubernetes-management/templates/kubernetes-manager-configmap.yaml b/helm-charts/core/ci/local_chart/kubernetes-management/templates/kubernetes-manager-configmap.yaml
index a8dd052b646..c2a930b027a 100644
--- a/helm-charts/core/ci/local_chart/kubernetes-management/templates/kubernetes-manager-configmap.yaml
+++ b/helm-charts/core/ci/local_chart/kubernetes-management/templates/kubernetes-manager-configmap.yaml
@@ -135,6 +135,9 @@ data:
rsaPrivateKey: |
{{- .Values.kubernetesManager.apiserver.auth.rsaPrivateKey | nindent 10 }}
+ docker:
+ enable: {{ .Values.kubernetesManager.docker.enable }}
+
{{ if .Values.kubeConfig.useKubeConfig -}}
kubeConfig.yaml: |
{{- .Values.kubeConfig.content | nindent 4 }}
diff --git a/helm-charts/core/ci/local_chart/kubernetes-management/values.yaml b/helm-charts/core/ci/local_chart/kubernetes-management/values.yaml
index c11f424f3c2..dee96681d3c 100644
--- a/helm-charts/core/ci/local_chart/kubernetes-management/values.yaml
+++ b/helm-charts/core/ci/local_chart/kubernetes-management/values.yaml
@@ -94,6 +94,7 @@ service:
# kubernetesManager Deployment
kubernetesManager:
enabled: true
+ debug: false
replicas: 1
resources:
requests:
@@ -147,11 +148,23 @@ kubernetesManager:
apiToken:
key: Devops-Token
value: landun
- rsaPrivateKey: |
+ rsaPrivateKey: ""
volumeMount:
# 流水线构建工作空间和agent日志在容器内的挂载点
dataPath: /data/devops/workspace
logPath: /data/devops/logs
+ # manager使用docker相关配置,会启用特权模式容器
+ docker:
+ enable: true
+ image: docker:24.0.1-dind
+ resources:
+ requests:
+ cpu: 50m
+ memory: 512Mi
+ limits:
+ cpu: 100m
+ memory: 1024Mi
+
dockerInit:
# 是否使用当前chart的 dockerinit.sh
useDockerInit: true
diff --git a/helm-charts/core/ci/templates/gateway/deployment.yaml b/helm-charts/core/ci/templates/gateway/deployment.yaml
index f1617fa095b..b5329e0cf51 100644
--- a/helm-charts/core/ci/templates/gateway/deployment.yaml
+++ b/helm-charts/core/ci/templates/gateway/deployment.yaml
@@ -63,8 +63,6 @@ spec:
- "-c"
- |
cp -r /data/workspace/frontend/* /tmp/frontend/
- sysctl -w net.ipv4.tcp_tw_reuse=0
- sysctl -w net.ipv4.tcp_max_tw_buckets=16384
containers:
- name: gateway
image: {{ include "bkci-gateway.image" . }}
diff --git a/helm-charts/core/ci/templates/init/init.bkrepo.yaml b/helm-charts/core/ci/templates/init/init.bkrepo.yaml
index ef3035e3f68..9d16cb9dd4e 100644
--- a/helm-charts/core/ci/templates/init/init.bkrepo.yaml
+++ b/helm-charts/core/ci/templates/init/init.bkrepo.yaml
@@ -33,7 +33,7 @@ spec:
REPO_CREATE_GENERIC_PATH="{{ .Values.config.bkRepoApiUrl }}/repository/api/repo/create"
REPO_INIT_GENERIC_METADATA_PATH="{{ .Values.config.bkRepoApiUrl }}/generic/"
create_repo_project_name_init_plugintransfer_project_generic (){
- for i in bk-store
+ for i in bk-store bkcdn
do
ret=0
echo "CI project is $i -------------------------------------------------->"
diff --git a/helm-charts/core/ci/templates/init/init.iam-rbac.yaml b/helm-charts/core/ci/templates/init/init.iam-rbac.yaml
index b802482e8a2..dd9d035f73e 100644
--- a/helm-charts/core/ci/templates/init/init.iam-rbac.yaml
+++ b/helm-charts/core/ci/templates/init/init.iam-rbac.yaml
@@ -21,13 +21,13 @@ spec:
- name: init-iam
image: {{ include "bkci-backend.image" . }}
imagePullPolicy: {{ .Values.backendImage.pullPolicy }}
- workingDir: /data/workspace/support-files/
+ workingDir: /data/workspace/support-files/bkiam-rbac
command:
- "/bin/bash"
- "-c"
- |
# 修改auth链接
- sed -i 's/ci-auth.service.consul:21936/{{- .Values.config.bkCiHost -}}\/auth/g' bkiam-rbac/*.json
+ sed -i 's/ci-auth.service.consul:21936/{{- .Values.config.bkCiHost -}}\/auth/g' *.json
# 导入模型
for i in $(find . -name '*.json'|sort)
do
@@ -47,8 +47,8 @@ spec:
# 注册auth回调
echo "{{ include "bkci.names.fullname" . }}-auth is available";
- sed -i 's/bk-ci.service.consul/{{ include "bkci.names.fullname" . }}-gateway.{{ .Release.Namespace }}/g' ms-init/auth/iam-callback-resource-registere.conf
- iam_json_file="ms-init/auth/iam-callback-resource-registere.conf"
+ sed -i 's/bk-ci.service.consul/{{ include "bkci.names.fullname" . }}-gateway.{{ .Release.Namespace }}/g' ../ms-init/auth/iam-callback-resource-registere.conf
+ iam_json_file="../ms-init/auth/iam-callback-resource-registere.conf"
curl -X POST -H "Content-Type:application/json" -d "@$iam_json_file" "http://{{ include "bkci.names.fullname" . }}-auth.{{ .Release.Namespace }}.svc.cluster.local/api/op/auth/iam/callback/"
restartPolicy: OnFailure
{{- end -}}
diff --git a/helm-charts/core/ci/templates/init/init.iam.yaml b/helm-charts/core/ci/templates/init/init.iam.yaml
deleted file mode 100644
index 984171b3307..00000000000
--- a/helm-charts/core/ci/templates/init/init.iam.yaml
+++ /dev/null
@@ -1,56 +0,0 @@
-# 初始化iam
-{{ if .Values.init.iam }}
-{{- if eq .Values.config.bkCiAuthProvider "bk_login_v3" -}}
-apiVersion: batch/v1
-kind: Job
-metadata:
- name: {{ include "bkci.names.fullname" . }}-init-iam
- labels: {{- include "bkci.labels.standard" . | nindent 4 }}
- app.kubernetes.io/component: init-iam
- annotations:
- "helm.sh/hook": post-install,post-upgrade
- "helm.sh/hook-weight": "-4"
- "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
-spec:
- template:
- metadata:
- labels: {{- include "bkci.labels.standard" . | nindent 8 }}
- app.kubernetes.io/component: init-iam
- spec:
- containers:
- - name: init-iam
- image: {{ include "bkci-backend.image" . }}
- imagePullPolicy: {{ .Values.backendImage.pullPolicy }}
- workingDir: /data/workspace/support-files/
- {{ $mysqlData := split ":" (include "bkci.mysqlAddr" .) }}
- command:
- - "/bin/bash"
- - "-c"
- - |
- # 修改auth链接
- sed -i 's/ci-auth.service.consul:21936/{{- .Values.config.bkCiHost -}}\/auth/g' bkiam/*.json
- # 导入模型
- for i in $(find . -name '*.json'|sort)
- do
- python3 bkiam_do_migrate.py -t {{ .Values.config.bkIamPrivateUrl }} -a "{{ .Values.config.bkCiAppCode }}" -s "{{ .Values.config.bkCiAppToken }}" -f $i
- done
-
- services="auth"
- for service in $services
- do
- until curl --connect-timeout 3 -m 1 -s "http://{{ include "bkci.names.fullname" . }}-$service.{{ .Release.Namespace }}.svc.cluster.local" > nohup
- do
- echo "waiting for {{ include "bkci.names.fullname" . }}-$service";
- sleep 2;
- done
- echo "{{ include "bkci.names.fullname" . }}-$service is available";
- done
-
- # 注册auth回调
- echo "{{ include "bkci.names.fullname" . }}-auth is available";
- sed -i 's/bk-ci.service.consul/{{ include "bkci.names.fullname" . }}-gateway.{{ .Release.Namespace }}/g' ms-init/auth/iam-callback-resource-registere.conf
- iam_json_file="ms-init/auth/iam-callback-resource-registere.conf"
- curl -X POST -H "Content-Type:application/json" -d "@$iam_json_file" "http://{{ include "bkci.names.fullname" . }}-auth.{{ .Release.Namespace }}.svc.cluster.local/api/op/auth/iam/callback/"
- restartPolicy: OnFailure
-{{- end -}}
-{{- end -}}
diff --git a/src/agent/agent-slim/cmd/translation_generator/translation_generator.go b/src/agent/agent-slim/cmd/translation_generator/translation_generator.go
index c6bb4612542..f48fc746b07 100644
--- a/src/agent/agent-slim/cmd/translation_generator/translation_generator.go
+++ b/src/agent/agent-slim/cmd/translation_generator/translation_generator.go
@@ -156,7 +156,7 @@ func main() {
}
}
-// 生成器保存分析的状态。 主要用来缓冲 format.Source 的输出。
+// Generator 生成器保存分析的状态。 主要用来缓冲 format.Source 的输出。
type Generator struct {
buf bytes.Buffer // 累计输出
}
diff --git a/src/agent/agent-slim/pkg/constant/constant.go b/src/agent/agent-slim/pkg/constant/constant.go
index be131a15722..38a656b6600 100644
--- a/src/agent/agent-slim/pkg/constant/constant.go
+++ b/src/agent/agent-slim/pkg/constant/constant.go
@@ -1,11 +1,11 @@
package constant
const (
- // 构建机默认国际化语言
- DEFAULT_LANGUAGE_TYPE = "zh_CN"
- // 构建机接取任务间隔时间
+ // DefaultLanguageType 构建机默认国际化语言
+ DefaultLanguageType = "zh_CN"
+ // BuildIntervalInSeconds 构建机接取任务间隔时间
BuildIntervalInSeconds = 5
- // api 鉴权的头信息
+ // AuthHeaderBuildType api 鉴权的头信息
AuthHeaderBuildType = "X-DEVOPS-BUILD-TYPE" // 构建类型
AuthHeaderProjectId = "X-DEVOPS-PROJECT-ID" // 项目ID
AuthHeaderAgentId = "X-DEVOPS-AGENT-ID" // Agent ID
diff --git a/src/agent/agent-slim/pkg/i18n/i18n.go b/src/agent/agent-slim/pkg/i18n/i18n.go
index a2e22d7960d..9b48a584ed6 100644
--- a/src/agent/agent-slim/pkg/i18n/i18n.go
+++ b/src/agent/agent-slim/pkg/i18n/i18n.go
@@ -44,7 +44,7 @@ import (
var localizer *localizerType
-var defaultLocalTag = language.Make(constant.DEFAULT_LANGUAGE_TYPE)
+var defaultLocalTag = language.Make(constant.DefaultLanguageType)
type localizerType struct {
nowLocalizer language.Tag
diff --git a/src/agent/agent-slim/pkg/job/build_manager.go b/src/agent/agent-slim/pkg/job/build_manager.go
index bd919005a05..7d078e7c5f7 100644
--- a/src/agent/agent-slim/pkg/job/build_manager.go
+++ b/src/agent/agent-slim/pkg/job/build_manager.go
@@ -27,7 +27,7 @@ var GBuildManager *buildManager
func init() {
GBuildManager = &buildManager{
lock: &sync.RWMutex{},
- instances: make(map[int]*buildData, 0),
+ instances: make(map[int]*buildData),
}
}
diff --git a/src/agent/agent/.gitignore b/src/agent/agent/.gitignore
new file mode 100644
index 00000000000..b59f7e3a95a
--- /dev/null
+++ b/src/agent/agent/.gitignore
@@ -0,0 +1 @@
+test/
\ No newline at end of file
diff --git a/src/agent/agent/README.md b/src/agent/agent/README.md
index 11efd728a30..388c396458b 100644
--- a/src/agent/agent/README.md
+++ b/src/agent/agent/README.md
@@ -1,6 +1,7 @@
# Agent(Golang)
-构建Agent是指包含了agent进程监控和调度部分逻辑的代码,不包含与流水线交互的构建类业务逻辑代码,需要与另外一个worker(kotlin) 一起整合才能是完整的Agent包。
+构建Agent是指包含了agent进程监控和调度部分逻辑的代码,不包含与流水线交互的构建类业务逻辑代码,需要与另外一个worker(kotlin)
+一起整合才能是完整的Agent包。
## Agent二进制程序编译
@@ -14,7 +15,8 @@ windows编译,执行脚本 `build_windows.bat`
执行以上编译脚本或命令后,会在 `bin` 目录下生成对应的可执行文件。
-比如执行 `make clean build_linux` 命令会在 `bin` 目录下生成 `devopsDaemon_linux`、`devopsAgent_linux`、`upgrader_linux` 文件,其他系统依此类推。
+比如执行 `make clean build_linux` 命令会在 `bin` 目录下生成 `devopsDaemon_linux`、`devopsAgent_linux`、`upgrader_linux`
+文件,其他系统依此类推。
- devopsDaemon: 用于守护agent进程,监控和拉起agent进程
- devopsAgent: 用于和调度服务通信,以及拉起构建进程worker
@@ -29,32 +31,49 @@ windows编译,执行脚本 `build_windows.bat`
- scripts/linux/stop.sh: agent停止脚本
- scripts/linux/uninstall.sh: agent卸载脚本
-
## 架构设计说明
+
### Agent 模块说明
+
agent模块为GoAgent的核心模块。主要负责**执行worker以及做相关辅助工作**。
+
#### 模块主流程说明
+
![image](https://github.com/Tencent/bk-ci/blob/master/docs/resource/img/Agent%E6%A8%A1%E5%9D%97%E6%B5%81%E7%A8%8B%E5%9B%BE.png)
+
#### 步骤说明
+
针对流程图步骤补充说明,序号为流程图步骤序号。
+
##### 1 检查进程。
-主要通过 **CheckProcess** 函数,函数主要通过输入的模块名称 例如:agent,获取runtime目录下的 name.pid 和 name.lock 文件。通过是否可以拿到 name.lock 文件锁的锁,来判断当前进程是否正在运行,如若没有在运行,则获取全局锁 total-lock.lock 来修改 name.pid 文件写入当前agent进程ID,同时一直持有 name.lock 锁直到进程退出时自动释放。
+
+主要通过 **CheckProcess** 函数,函数主要通过输入的模块名称 例如:agent,获取runtime目录下的 name.pid 和 name.lock
+文件。通过是否可以拿到 name.lock 文件锁的锁,来判断当前进程是否正在运行,如若没有在运行,则获取全局锁 total-lock.lock 来修改
+name.pid 文件写入当前agent进程ID,同时一直持有 name.lock 锁直到进程退出时自动释放。
##### 2 初始化配置。
-1. 从 **.agent.properties** 文件中读取agent配置信息到 **GAgentConfig** 对象中。在读取的同时会写入一次,将 GAgentConfig 对象初始化的一些值持久化到 .agent.properties中。
+
+1. 从 **.agent.properties** 文件中读取agent配置信息到 **GAgentConfig** 对象中。在读取的同时会写入一次,将 GAgentConfig
+ 对象初始化的一些值持久化到 .agent.properties中。
2. 初始化证书。 如果根目录中存在 **.cert** 文件,则将其添加至系统证书池,并添加至agent发送https请求的 **TLS** 配置中
-3. 初始化Agent环境变量。读取系统一些agent可能用到的环境变量到agent **GAgentEnv** 中,方便后续使用,例如 HostName,osName等。注:windows系统在这一步中因为可能持有虚拟网卡的IP,所以在上报agentIP地址时会 **忽略被配置了忽略虚拟网卡的windows机器IP**。
+3. 初始化Agent环境变量。读取系统一些agent可能用到的环境变量到agent **GAgentEnv** 中,方便后续使用,例如
+ HostName,osName等。注:windows系统在这一步中因为可能持有虚拟网卡的IP,所以在上报agentIP地址时会 *
+ *忽略被配置了忽略虚拟网卡的windows机器IP**。
##### 3 上报后台Agent启动。
+
**POST|env服务|agent/thirdPartyAgent/startup** 并解析返回结果,如果成功返回则执行后续步骤否则退出。
##### A 数据采集。
+
通过配置替换代码中写好的采集配置,启动 **telegraf** agent,并将数据上报到后台的influxDB。
##### B 心跳上报。
+
无限循环,10s一次。通过 **POST|env服务|agent/thirdPartyAgent/agents/newHeartbeat** 发送agent环境的一些配置到后台,并解析后台结果,修改部分agent配置。
##### C 检查升级。无限循环,20s一次。
+
1. 获取当前jdk版本信息
2. 通过 **POST|dispatch环境|agent/thirdPartyAgent/upgradeNew** 上报agent,worker,jdk版本信息判断是否需要升级。不需要升级则直接返回。
3. 下载最新版本应用对比md5判断是否需要升级。不需要升级则直接返回。
@@ -64,42 +83,62 @@ agent模块为GoAgent的核心模块。主要负责**执行worker以及做相关
7. 升级agent。执行 **upgrader** 模块。
##### D pipeline。无限循环,30s一次。
+
1. 通过 **GET|env服务|agent/thirdPartyAgent/agents/pipelines** 获取需要执行的pipeline任务。
2. 通过 **PUT|env服务|agent/thirdPartyAgent/agents/pipelines** 更新任务状态。
3. 将任务脚本写入 工作空间下 **devops_pipeline_SeqId_type.sh** 文件。执行后获取输出内容,并通过更新任务状态上报后台,同时删除脚本文件。
##### E 定期清理。
+
无限循环,2小时一次。删除超过配置中 **LogsKeepHours**的垃圾文件(hs_err_pid前缀文件)和日志文件。
##### 4 从后台拉取构建任务。无限循环,5s一次。
+
1. 调用 **GET|env服务|agent/thirdPartyAgent/status** 获取agent状态,如果状态返回不正常则跳过这次任务。
2. 判断当前运行的instance是否超过配置 **ParallelTaskCount** 最大任务数,如果超过则跳过循环。
3. 获取**构建锁**,防止与其他任务差生冲突。
-4. 通过 **GET|dispatch服务|agent/thirdPartyAgent/startup** 获取构建任务,如果任务为空则跳过这次。否则则添加**预处理任务**到 **GBuildManager** 对象。注:unix构建机受**非登录用户启动进程无法拿到 ~/.bashrc 中的环境变量**的影响,需要创建 prestart和start脚本,通过设置 **exec -l** 来通过当前用户启动。
+4. 通过 **GET|dispatch服务|agent/thirdPartyAgent/startup** 获取构建任务,如果任务为空则跳过这次。否则则添加**预处理任务**到
+ **GBuildManager** 对象。注:unix构建机受**非登录用户启动进程无法拿到 ~/.bashrc 中的环境变量**的影响,需要创建
+ prestart和start脚本,通过设置 **exec -l** 来通过当前用户启动。
##### 5 启动构建。
-1. 获取工作空间下的 **worker.jar** 文件。如果没有则尝试通过获取工作空间下的 **tmp** 目录下中同名文件进行复制使用来尝试自愈,如果 tmp 目录中的worker版本不对或者不存在文件,则进行 **结束构建**逻辑。
-2. 在工作空间下创建 **build_tmp** 目录,并在目录下启动 worker进程执行构建任务。任务启动后删除**预处理任务**同时添加**任务实例**到 **GBuildManager** 对象。
+
+1. 获取工作空间下的 **worker.jar** 文件。如果没有则尝试通过获取工作空间下的 **tmp** 目录下中同名文件进行复制使用来尝试自愈,如果
+ tmp 目录中的worker版本不对或者不存在文件,则进行 **结束构建**逻辑。
+2. 在工作空间下创建 **build_tmp** 目录,并在目录下启动 worker进程执行构建任务。任务启动后删除**预处理任务**同时添加**任务实例
+ **到 **GBuildManager** 对象。
##### F 等待进程结束
+
通过 **process.Wait()** 来等待进程结束,删除**GBuildManager** 对象中的任务实例,并执行 **结束构建**逻辑。
+
##### G 清理构建空间,即结束构建逻辑。
+
- 清理构建过程中产生的文件脚本,与 build_tmp目录下超过7天的文件。
- 通过**POST|dispathc服务|agent/thirdPartyAgent/workerBuildFinish** 上报后台任务结束。
-
-
### Daemon 模块说明
+
daemon模块是agent模块的守护进程,主要功能是维护agent进程一直运行。
daemon模块在windows系统和unix系统中有不同的实现
+
#### windows实现
+
win实现主要是靠 **github.com/kardianos/service** 库调用的windows service功能实现,通过实现库中service接口维护agent一直运行。
+
#### unix实现
-unix中的实现主要通过使用**定时器,5s一次**检查Agent模块进程是否存在,检测方式通过获取agent的文件锁,进程推出后文件锁会自动释放,所以如果无法获取文件锁,说明进程正常运行,如果可以获取文件锁,则说明agent进程退出了,这时Daemon会将其拉起。
+
+unix中的实现主要通过使用**定时器,5s一次**
+检查Agent模块进程是否存在,检测方式通过获取agent的文件锁,进程推出后文件锁会自动释放,所以如果无法获取文件锁,说明进程正常运行,如果可以获取文件锁,则说明agent进程退出了,这时Daemon会将其拉起。
### Install & Upgrade 模块说明
+
安装和升级模块,主要负责daemon模块和agent模块的升级。
+
#### install模块
+
安装模块功能较为简单,主要通过调用安装脚本,安装agent。
+
#### upgrade模块
+
升级模块和agent模块中的升级Agent的逻辑一致,通过杀掉Agent进程后,替换Agent文件并启动来完成升级。
diff --git a/src/agent/agent/go.mod b/src/agent/agent/go.mod
index 5d3ffeb3254..0a13800cefe 100644
--- a/src/agent/agent/go.mod
+++ b/src/agent/agent/go.mod
@@ -4,20 +4,19 @@ go 1.19
require (
github.com/TencentBlueKing/bk-ci/agentcommon v0.0.0-00010101000000-000000000000
- github.com/docker/docker v23.0.3+incompatible
+ github.com/docker/docker v24.0.9+incompatible
github.com/gofrs/flock v0.8.1
// 1.24 以上的版本引入了memcall和memguard会导致
// 1、ulimit corefile被设置为0 https://github.com/ci-plugins/memguard/blob/master/core/init.go
// 2、arm64 linux panic报错 https://github.com/awnumar/memguard/issues/144
github.com/influxdata/telegraf v1.24.4
- github.com/kardianos/service v1.2.2
github.com/nicksnyder/go-i18n/v2 v2.2.1
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.9.3
- golang.org/x/text v0.7.0
+ golang.org/x/text v0.15.0
gopkg.in/ini.v1 v1.67.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
- gotest.tools/v3 v3.0.3
+ gotest.tools/v3 v3.5.0
)
require (
@@ -32,9 +31,9 @@ require (
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
- github.com/golang/protobuf v1.5.2 // indirect
+ github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
- github.com/google/go-cmp v0.5.9 // indirect
+ github.com/google/go-cmp v0.6.0 // indirect
github.com/gosnmp/gosnmp v1.35.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/influxdata/toml v0.0.0-20190415235208-270119a8ce65 // indirect
@@ -46,7 +45,7 @@ require (
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/naoina/go-stringutil v0.1.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
- github.com/opencontainers/image-spec v1.1.0-rc2 // indirect
+ github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b // indirect
github.com/philhofer/fwd v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect
@@ -57,17 +56,17 @@ require (
// 1.24 telegraf 必须跟随 3.22.9 版本,之上的版本windows编译不通过
github.com/shirou/gopsutil/v3 v3.22.9 // indirect
github.com/sleepinggenius2/gosmi v0.4.4 // indirect
- github.com/stretchr/objx v0.5.0 // indirect
- github.com/stretchr/testify v1.8.1 // indirect
+ github.com/stretchr/objx v0.5.2 // indirect
+ github.com/stretchr/testify v1.9.0 // indirect
github.com/tinylib/msgp v1.1.6 // indirect
- github.com/tklauser/go-sysconf v0.3.11 // indirect
- github.com/tklauser/numcpus v0.6.0 // indirect
+ github.com/tklauser/go-sysconf v0.3.12 // indirect
+ github.com/tklauser/numcpus v0.6.1 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
- github.com/yusufpapurcu/wmi v1.2.2 // indirect
- golang.org/x/net v0.7.0 // indirect
- golang.org/x/sys v0.6.0 // indirect
- google.golang.org/protobuf v1.28.1 // indirect
+ github.com/yusufpapurcu/wmi v1.2.4 // indirect
+ golang.org/x/net v0.23.0 // indirect
+ golang.org/x/sys v0.20.0
+ google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
@@ -75,11 +74,17 @@ require (
require (
github.com/fsouza/go-dockerclient v1.9.7
github.com/gorilla/websocket v1.5.0
- golang.org/x/sync v0.1.0
+ golang.org/x/sync v0.3.0
)
require (
- cloud.google.com/go/compute v1.10.0 // indirect
+ cloud.google.com/go v0.110.4 // indirect
+ cloud.google.com/go/bigquery v1.52.0 // indirect
+ cloud.google.com/go/compute v1.21.0 // indirect
+ cloud.google.com/go/compute/metadata v0.2.3 // indirect
+ cloud.google.com/go/iam v1.1.1 // indirect
+ cloud.google.com/go/monitoring v1.15.1 // indirect
+ cloud.google.com/go/pubsub v1.32.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/aws/aws-sdk-go-v2 v1.17.1 // indirect
github.com/aws/aws-sdk-go-v2/config v1.17.8 // indirect
@@ -94,33 +99,41 @@ require (
github.com/aws/aws-sdk-go-v2/service/sts v1.17.4 // indirect
github.com/aws/smithy-go v1.13.4 // indirect
github.com/blues/jsonata-go v1.5.4 // indirect
- github.com/containerd/containerd v1.6.18 // indirect
+ github.com/containerd/containerd v1.6.26 // indirect
+ github.com/docker/distribution v2.8.2+incompatible // indirect
+ github.com/go-logr/logr v1.4.1 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
+ github.com/google/s2a-go v0.1.4 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
- github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
+ github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
github.com/klauspost/compress v1.15.11 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/moby/patternmatcher v0.5.0 // indirect
github.com/moby/sys/sequential v0.5.0 // indirect
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
github.com/morikuni/aec v1.0.0 // indirect
- github.com/opencontainers/runc v1.1.5 // indirect
+ github.com/opencontainers/runc v1.1.12 // indirect
+ github.com/rickb777/date v1.14.2 // indirect
+ github.com/rickb777/plural v1.2.2 // indirect
+ github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
- go.opencensus.io v0.23.0 // indirect
- golang.org/x/crypto v0.5.0 // indirect
- golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
- golang.org/x/oauth2 v0.3.0 // indirect
- golang.org/x/tools v0.1.12 // indirect
- google.golang.org/api v0.100.0 // indirect
+ go.opencensus.io v0.24.0 // indirect
+ golang.org/x/crypto v0.23.0 // indirect
+ golang.org/x/mod v0.10.0 // indirect
+ golang.org/x/oauth2 v0.10.0 // indirect
+ golang.org/x/tools v0.9.1 // indirect
+ google.golang.org/api v0.126.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a // indirect
- google.golang.org/grpc v1.50.1 // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
+ google.golang.org/grpc v1.58.3 // indirect
)
require (
+ github.com/capnspacehook/taskmaster v0.0.0-20210519235353-1629df7c85e9
github.com/docker/cli v23.0.1+incompatible
- github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/go-connections v0.4.0
+ github.com/kardianos/service v1.2.2
+ github.com/shirou/gopsutil/v4 v4.24.5
github.com/spf13/pflag v1.0.5
)
diff --git a/src/agent/agent/go.sum b/src/agent/agent/go.sum
index 0ab43478a43..e4e2e0b2e08 100644
--- a/src/agent/agent/go.sum
+++ b/src/agent/agent/go.sum
@@ -19,26 +19,33 @@ cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKP
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
-cloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8=
+cloud.google.com/go v0.110.4 h1:1JYyxKMN9hd5dR2MYTPWkGUgcoxVVhg0LKNKEo0qvmk=
+cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/bigquery v1.42.0 h1:JuTk8po4bCKRwObdT0zLb1K0BGkGHJdtgs2GK3j2Gws=
+cloud.google.com/go/bigquery v1.52.0 h1:JKLNdxI0N+TIUWD6t9KN646X27N5dQWq9dZbbTWZ8hc=
+cloud.google.com/go/bigquery v1.52.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4=
cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o=
-cloud.google.com/go/compute v1.10.0 h1:aoLIYaA1fX3ywihqpBk2APQKOo20nXsp1GEZQbx5Jk4=
-cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU=
+cloud.google.com/go/compute v1.21.0 h1:JNBsyXVoOoNJtTQcnEY5uYpZIbeCTYIeDe0Xh1bySMk=
+cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
+cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
+cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
-cloud.google.com/go/iam v0.5.0 h1:fz9X5zyTWBmamZsqvqZqD7khbifcZF/q+Z1J8pfhIUg=
-cloud.google.com/go/monitoring v1.7.0 h1:zK12aN/jzLRzrRXopEOUaG6kvuF6WJmlv1mXn1L7a6E=
+cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y=
+cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
+cloud.google.com/go/monitoring v1.15.1 h1:65JhLMd+JiYnXr6j5Z63dUYCuOg770p8a/VC+gil/58=
+cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
-cloud.google.com/go/pubsub v1.26.0 h1:Y/HcMxVXgkUV2pYeLMUkclMg0ue6U0jVyI5xEARQ4zA=
+cloud.google.com/go/pubsub v1.32.0 h1:JOEkgEYBuUTHSyHS4TcqOFuWr+vD6qO/imsFqShUCp4=
+cloud.google.com/go/pubsub v1.32.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
@@ -48,6 +55,7 @@ code.cloudfoundry.org/clock v1.0.0 h1:kFXWQM4bxYvdBw2X8BbBeXwQNgfoWv1vqAk2ZZyBN2
collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE=
collectd.org v0.5.0 h1:y4uFSAuOmeVhG3GCRa3/oH+ysePfO/+eGJNfd0Qa3d8=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8 h1:V8krnnfGj4pV65YLUm3C0/8bl7V5Nry2Pwvy3ru/wLc=
github.com/Azure/azure-amqp-common-go/v3 v3.2.3 h1:uDF62mbd9bypXWi19V1bN5NZEO84JqgmI5G73ibAmrk=
github.com/Azure/azure-event-hubs-go/v3 v3.3.20 h1:LRAy00JlV5aDqd0LFXwfwFReYzl03CtH/kD91OHrT94=
github.com/Azure/azure-kusto-go v0.8.0 h1:AeO6VBRGzB1BhmWeheSyN+WSrx+1wmhHm47vzptitdw=
@@ -101,7 +109,7 @@ github.com/Mellanox/rdmamap v0.0.0-20191106181932-7c3c4763a6ee h1:atI/FFjXh6hIVl
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
-github.com/Microsoft/hcsshim v0.9.6 h1:VwnDOgLeoi2du6dAznfmspNqTiwczvjv4K7NxuY9jsY=
+github.com/Microsoft/hcsshim v0.9.10 h1:TxXGNmcbQxBKVWvjvTocNb6jrPyeHlk5EiDhhgHgggs=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
@@ -132,12 +140,14 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8V
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1836 h1:HY697lY0w1HInRKBy/IO0lGmsMj3YSSM32SwG2eLsWM=
github.com/amir/raidman v0.0.0-20170415203553-1ccc43bfb9c9 h1:FXrPTd8Rdlc94dKccl7KPmdmIbVh/OjelJ8/vgMRzcQ=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
+github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
github.com/antchfx/jsonquery v1.3.0 h1:rftVBKEXpj8C9WVu+4mbqL5hd6nLz7/AbIvAQlq3D7o=
github.com/antchfx/xmlquery v1.3.12 h1:6TMGpdjpO/P8VhjnaYPXuqT3qyJ/VsqoyNTmJzNBTQ4=
github.com/antchfx/xpath v1.2.1 h1:qhp4EW6aCOVr5XIkT+l6LJ9ck/JsUH/yyauNgTQkBF8=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0=
github.com/apache/arrow/go/arrow v0.0.0-20211112161151-bc219186db40 h1:q4dksr6ICHXqG5hm0ZW5IHyeEJXoIJSOZeBLmWPNeIQ=
+github.com/apache/arrow/go/v12 v12.0.0 h1:xtZE63VWl7qLdB0JObIXvvhGjoVNrQ9ciIHG2OK5cmc=
github.com/apache/iotdb-client-go v0.12.2-0.20220722111104-cd17da295b46 h1:28HyUQcr8ZCyCAatR0gkf9PuLr52U2T+66tx5Th0nxI=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
@@ -223,6 +233,8 @@ github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+Wji
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
github.com/caio/go-tdigest v3.1.0+incompatible h1:uoVMJ3Q5lXmVLCCqaMGHLBWnbGoN6Lpu7OAUPR60cds=
+github.com/capnspacehook/taskmaster v0.0.0-20210519235353-1629df7c85e9 h1:5jmtWADt5DzD8NnPxcqd1FzbFNZNfbJGNeDb+WKjoJ0=
+github.com/capnspacehook/taskmaster v0.0.0-20210519235353-1629df7c85e9/go.mod h1:257CYs3Wd/CTlLQ3c72jKv+fFE2MV3WPNnV5jiroYUU=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
@@ -232,12 +244,10 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
-github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
+github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
github.com/cisco-ie/nx-telemetry-proto v0.0.0-20220628142927-f4160bcb943c h1:k3y2XtIffIk230a+e0d7vbs5ebTvH3OcCMKN/jS6IAY=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@@ -245,19 +255,21 @@ github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
+github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
-github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
-github.com/containerd/containerd v1.6.18 h1:qZbsLvmyu+Vlty0/Ex5xc0z2YtKpIsb5n45mAMI+2Ns=
-github.com/containerd/containerd v1.6.18/go.mod h1:1RdCUu95+gc2v9t3IL+zIlpClSmew7/0YS8O5eQZrOw=
-github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
+github.com/containerd/containerd v1.6.26 h1:VVfrE6ZpyisvB1fzoY8Vkiq4sy+i5oF4uk7zu03RaHs=
+github.com/containerd/containerd v1.6.26/go.mod h1:I4TRdsdoo5MlKob5khDJS2EPT1l1oMNaE2MBm6FrwxM=
+github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/coocood/freecache v1.2.2 h1:UPkJCxhRujykq1jXuwxAPgDHnm6lKGrLZPnuHzgWRtE=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
-github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/couchbase/go-couchbase v0.1.1 h1:ClFXELcKj/ojyoTYbsY34QUrrYCBi/1G749sXSCkdhk=
github.com/couchbase/gomemcached v0.1.3 h1:HIc5qMYNbuhB7zNaiEtj61DCYkquAwrQlf64q7JzdEY=
@@ -267,7 +279,6 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -288,8 +299,8 @@ github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4Kfc
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v20.10.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v23.0.3+incompatible h1:9GhVsShNWz1hO//9BNg/dpMnZW25KydO4wtVxWAIbho=
-github.com/docker/docker v23.0.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0=
+github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
@@ -312,14 +323,15 @@ github.com/eclipse/paho.mqtt.golang v1.4.1 h1:tUSpviiL5G3P9SZZJPC4ZULZJsxQKXxfEN
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
-github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk=
-github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw=
+github.com/emicklei/go-restful v2.16.0+incompatible h1:rgqiKNjTnFQA6kkhFe16D8epTksy9HQ1MyrbDXSdYhM=
+github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ=
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@@ -331,7 +343,6 @@ github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoD
github.com/form3tech-oss/jwt-go v3.2.5+incompatible h1:/l4kBbb4/vGSsdtB5nUe8L7B9mImVMaBPw9L/0TBHU8=
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
-github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsouza/go-dockerclient v1.9.7 h1:FlIrT71E62zwKgRvCvWGdxRD+a/pIy+miY/n3MXgfuw=
github.com/fsouza/go-dockerclient v1.9.7/go.mod h1:vx9C32kE2D15yDSOMCDaAEIARZpDQDFBHeqL3MgQy/U=
@@ -355,7 +366,9 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
-github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
+github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
+github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
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-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI=
@@ -479,8 +492,7 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
-github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
@@ -527,8 +539,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
+github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@@ -537,7 +550,7 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/flatbuffers v1.11.0/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
-github.com/google/flatbuffers v2.0.0+incompatible h1:dicJ2oXwypfwUGnB2/TYWYEKiuk9eYQlQO/AnOHl5mI=
+github.com/google/flatbuffers v2.0.8+incompatible h1:ivUb1cGomAB101ZM1T0nOiWz9pSrTMoa9+EiY7igmkM=
github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
github.com/google/gnxi v0.0.0-20221016143401-2aeceb5a2901 h1:xlsMG0I0F6Ou3a4zRWu3cThivTt2N2V1cZafIloTBTU=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -553,8 +566,9 @@ 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.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-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/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
@@ -577,17 +591,19 @@ github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210323184331-8eee2492667d/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
+github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
-github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs=
-github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
+github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
+github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
-github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU=
+github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/gopcua/opcua v0.3.7 h1:iGjLW3D+ztnjtZQPKsJ0nwibHyDw1m11NfqOU8KSFQ8=
github.com/gophercloud/gophercloud v0.16.0/go.mod h1:wRtmUelyIIv3CSSDI47aUwbs075O6i+LY+pXsKCBsb4=
@@ -738,11 +754,14 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4=
github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
+github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5 h1:2U0HzY8BJ8hVwDKIzp7y4voR9CX/nvcfymLmg2UiOio=
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
+github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b h1:iNjcivnc6lhbvJA3LD622NPrUponluJrBWPIwGG/3Bg=
@@ -752,7 +771,6 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -813,6 +831,8 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA=
+github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs=
+github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI=
github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
@@ -837,7 +857,6 @@ github.com/moby/ipvs v1.0.2 h1:NSbzuRTvfneftLU3VwPU5QuA6NZ0IUmqq9+VHcQxqHw=
github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo=
github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
-github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
@@ -853,7 +872,6 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6f
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
-github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg=
github.com/multiplay/go-ts3 v1.0.1 h1:Ja8ho7UzUDNvNCwcDzPEPimLRub7MUqbD+sgMWkcR0A=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
@@ -881,6 +899,7 @@ github.com/nicksnyder/go-i18n/v2 v2.2.1 h1:aOzRCdwsJuoExfZhoiXHy4bjruwCMdt5otbYo
github.com/nicksnyder/go-i18n/v2 v2.2.1/go.mod h1:fF2++lPHlo+/kPaj3nB0uxtPwzlPm+BlgwGX7MkeGj0=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nsqio/go-nsq v1.1.0 h1:PQg+xxiUjA7V+TLdXw7nVrJ5Jbl3sN86EhGCQj4+FYE=
+github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
@@ -891,20 +910,22 @@ github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs=
+github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/openconfig/gnmi v0.0.0-20220920173703-480bf53a74d2 h1:3YLlQFLDsFTvruKoYBbuYqhCgsXMtNewSrLjNXcF/Sg=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
-github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034=
-github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
-github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
-github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
-github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
-github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
+github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b h1:YWuSjZCQAPM8UUBLkYUk1e+rZcvWHJmFb6i6rM44Xs8=
+github.com/opencontainers/image-spec v1.1.0-rc2.0.20221005185240-3a7f492d3f1b/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
+github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss=
+github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8=
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU=
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
@@ -997,6 +1018,10 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc=
+github.com/rickb777/date v1.14.2 h1:PCme7ZL/cniZmDgS9Pyn5fHmu5A6lz12Ibfd33FmDiw=
+github.com/rickb777/date v1.14.2/go.mod h1:swmf05C+hN+m8/Xh7gEq3uB6QJDNc5pQBWojKdHetOs=
+github.com/rickb777/plural v1.2.2 h1:4CU5NiUqXSM++2+7JCrX+oguXd2D7RY5O1YisMw1yCI=
+github.com/rickb777/plural v1.2.2/go.mod h1:xyHbelv4YvJE51gjMnHvk+U2e9zIysg6lTnSQK8XUYA=
github.com/riemann/riemann-go-client v0.5.1-0.20211206220514-f58f10cdce16 h1:bGXoxRwUpPTCaQ86DRE+3wqE9vh3aH8W0HH5L/ygOFM=
github.com/robbiet480/go.nut v0.0.0-20220219091450-bd8f121e1fa1 h1:YmFqprZILGlF/X3tvMA4Rwn3ySxyE3hGUajBHkkaZbM=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
@@ -1017,12 +1042,16 @@ github.com/samuel/go-zookeeper v0.0.0-20200724154423-2164a8ac840e h1:CGjiMQ0wMH4
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210223165440-c65ae3540d44/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
-github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA=
github.com/shirou/gopsutil/v3 v3.22.9/go.mod h1:bBYl1kjgEJpWpxeHmLI+dVHWtyAwfcmSBLDsp2TNT8A=
+github.com/shirou/gopsutil/v4 v4.24.5 h1:gGsArG5K6vmsh5hcFOHaPm87UD003CaDMkAOweSQjhM=
+github.com/shirou/gopsutil/v4 v4.24.5/go.mod h1:aoebb2vxetJ/yIDZISmduFvVNPHqXQ9SEJwRXxkf0RA=
+github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
+github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
+github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/showwin/speedtest-go v1.2.1 h1:5GrQFGn5N4YRBCaiph6ay6Py9yL2k7Ja10bbUZl9HPE=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
@@ -1037,7 +1066,6 @@ github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
-github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sleepinggenius2/gosmi v0.4.4 h1:xgu+Mt7CptuB10IPt3SVXBAA9tARToT4B9xGzjjxQX8=
@@ -1063,8 +1091,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
-github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -1074,9 +1103,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
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/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
+github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/testcontainers/testcontainers-go v0.14.0 h1:h0D5GaYG9mhOWr2qHdEKDXpkce/VlvaYOCzTRi6UBi8=
github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
@@ -1086,11 +1115,11 @@ github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDW
github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw=
github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw=
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
-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/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
+github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
-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/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
+github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
@@ -1100,9 +1129,7 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vapourismo/knx-go v0.0.0-20220829185957-fb5458a5389d h1:BJMc7MNW/p80cCkC46JimNuowOWCnSSW5IHjtUrXzNk=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
-github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs=
-github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/vishvananda/netns v0.0.0-20220913150850-18c4f4234207 h1:nn7SOQy8xCu3iXNv7oiBhhEQtbWdnEOMnuKBlHvrqIM=
github.com/vjeantet/grok v1.0.1 h1:2rhIR7J4gThTgcZ1m2JY4TrJZNgjn985U28kT2wQrJ4=
github.com/vmware/govmomi v0.28.1-0.20220921224932-b4b508abf208 h1:IDVzGQ2aczmTEfTos4hzmFw20tGQ4zZsVnel9C6VEpA=
@@ -1133,8 +1160,10 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da h1:NimzV1aGyq29m5ukMK0AMWEhFaL/lrEOaephfuoiARg=
-github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
+github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
+github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
@@ -1154,9 +1183,11 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
-go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
+go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
+go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/collector/pdata v0.63.0 h1:YPeMzF4OYFeMW6E+A/eQEv5s32wpc5wEa24H2PP5LeE=
+go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
@@ -1189,8 +1220,9 @@ golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWP
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
-golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
+golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1228,8 +1260,9 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
+golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1264,11 +1297,13 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
+golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
+golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@@ -1279,9 +1314,10 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210324051636-2c4c8ecb7826/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
+golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1294,8 +1330,8 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8=
-golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk=
+golang.org/x/oauth2 v0.10.0 h1:zHCpF2Khkwy4mMB4bv0U37YtJdTGW8jI0glAApi0Kh8=
+golang.org/x/oauth2 v0.10.0/go.mod h1:kTpgurOux7LqtuxjuyZa4Gj2gdezIt/jQtGnNFfypQI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -1309,8 +1345,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
-golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1331,18 +1367,18 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/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-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1384,25 +1420,24 @@ golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210314195730-07df6a141424/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/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/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
+golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
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=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1410,16 +1445,18 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y=
+golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -1490,8 +1527,9 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
-golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
+golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1527,8 +1565,8 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
google.golang.org/api v0.42.0/go.mod h1:+Oj4s6ch2SEGtPjGqfUfZonBH0GjQH89gTeKKAEGZKI=
-google.golang.org/api v0.100.0 h1:LGUYIrbW9pzYQQ8NWXlaIVkgnfubVBZbMFb9P8TK374=
-google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70=
+google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o=
+google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@@ -1580,8 +1618,10 @@ google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210312152112-fc591d9ea70f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a h1:GH6UPn3ixhWcKDhpnEC55S75cerLPdpp3hrhfKYjZgw=
-google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
+google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWotvtrwxFNrNE9CUAGtplaDK5NNI/g=
+google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
@@ -1605,8 +1645,9 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY=
-google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
+google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
+google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ=
+google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -1619,9 +1660,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
-google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
+google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -1665,8 +1705,9 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
-gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
+gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY=
+gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/src/agent/agent/internal/third_party/dep/fs/fs.go b/src/agent/agent/internal/third_party/dep/fs/fs.go
index 69cb76efe2c..3ed8ee66d59 100644
--- a/src/agent/agent/internal/third_party/dep/fs/fs.go
+++ b/src/agent/agent/internal/third_party/dep/fs/fs.go
@@ -32,6 +32,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package fs
import (
+ "fmt"
"github.com/pkg/errors"
"io"
"os"
@@ -41,7 +42,7 @@ import (
)
// fs contains a copy of a few functions from dep tool code to avoid a dependency on golang/dep.
-// This code is copied from https://github.com/golang/dep/blob/a5440af88cd9b4507810256f8845a297936868a2/internal/fs/fs.go
+// This code is copied from https://github.com/golang/dep/blob/master/internal/fs/fs.go
// No changes to the code were made other than removing some unused functions
// RenameWithFallback attempts to rename a file or directory, but falls back to
@@ -50,7 +51,7 @@ import (
func RenameWithFallback(src, dst string) error {
_, err := os.Stat(src)
if err != nil {
- return errors.Wrapf(err, "cannot stat %s", src)
+ return errors.Wrapf(err, "cannot stat %s error", src)
}
err = os.Rename(src, dst)
@@ -91,7 +92,7 @@ func IsDir(name string) (bool, error) {
return false, err
}
if !fi.IsDir() {
- return false, errors.Errorf("%q is not a directory", name)
+ return false, fmt.Errorf("%q is not a directory", name)
}
return true, nil
}
diff --git a/src/agent/agent/internal/third_party/dep/fs/rename.go b/src/agent/agent/internal/third_party/dep/fs/rename.go
index 277e9b72973..f9b79c89ede 100644
--- a/src/agent/agent/internal/third_party/dep/fs/rename.go
+++ b/src/agent/agent/internal/third_party/dep/fs/rename.go
@@ -35,10 +35,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package fs
import (
+ "github.com/pkg/errors"
"os"
"syscall"
-
- "github.com/pkg/errors"
)
// renameFallback attempts to determine the appropriate fallback to failed rename
diff --git a/src/agent/agent/internal/third_party/dep/fs/rename_windows.go b/src/agent/agent/internal/third_party/dep/fs/rename_windows.go
index d8207cc5f7a..bc4ef9e4d43 100644
--- a/src/agent/agent/internal/third_party/dep/fs/rename_windows.go
+++ b/src/agent/agent/internal/third_party/dep/fs/rename_windows.go
@@ -35,10 +35,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package fs
import (
+ "github.com/pkg/errors"
"os"
"syscall"
-
- "github.com/pkg/errors"
)
// renameFallback attempts to determine the appropriate fallback to failed rename
diff --git a/src/agent/agent/src/cmd/daemon/main.go b/src/agent/agent/src/cmd/daemon/main.go
index 248e7980bb9..c253eda5a08 100644
--- a/src/agent/agent/src/cmd/daemon/main.go
+++ b/src/agent/agent/src/cmd/daemon/main.go
@@ -32,6 +32,7 @@ package main
import (
"fmt"
+ "github.com/pkg/errors"
"io"
"os"
"os/exec"
@@ -102,6 +103,7 @@ func main() {
logs.Info("devops daemon start")
logs.Info("pid: ", os.Getpid())
+ logs.Info("workDir: ", workDir)
watch(isDebug)
systemutil.KeepProcessAlive()
@@ -120,7 +122,7 @@ func watch(isDebug bool) {
select {
case <-checkTimeTicker.C:
if err := totalLock.Lock(); err != nil {
- logs.Errorf("failed to get agent lock: %v", err)
+ logs.WithError(err).Error("failed to get agent lock")
continue
}
@@ -139,12 +141,12 @@ func doCheckAndLaunchAgent(isDebug bool) {
defer func() {
err = agentLock.Unlock()
if err != nil {
- logs.Error("try to unlock agent.lock failed", err)
+ logs.WithError(err).Error("try to unlock agent.lock failed")
}
}()
}
if err != nil {
- logs.Errorf("try to get agent.lock failed: %v", err)
+ logs.WithError(err).Error("try to get agent.lock failed")
return
}
if !locked {
@@ -155,7 +157,7 @@ func doCheckAndLaunchAgent(isDebug bool) {
process, err := launch(workDir+"/"+config.AgentFileClientLinux, isDebug)
if err != nil {
- logs.Errorf("launch agent failed: %v", err)
+ logs.WithError(err).Error("launch agent failed")
return
}
if process == nil {
@@ -182,38 +184,38 @@ func launch(agentPath string, isDebug bool) (*os.Process, error) {
err := fileutil.SetExecutable(agentPath)
if err != nil {
- return nil, fmt.Errorf("chmod agent file failed: %v", err)
+ return nil, errors.Wrap(err, "chmod agent file failed")
}
// 获取 agent 的错误输出,这样有助于打印出崩溃的堆栈方便排查问题
stdErr, errstd := cmd.StderrPipe()
if errstd != nil {
- logs.Error("get agent stderr pipe error", errstd)
+ logs.WithError(errstd).Error("get agent stderr pipe error")
}
if err = cmd.Start(); err != nil {
if stdErr != nil {
stdErr.Close()
}
- return nil, fmt.Errorf("start agent failed: %v", err)
+ return nil, errors.Wrap(err, "start agent failed")
}
go func() {
if err := cmd.Wait(); err != nil {
if exiterr, ok := err.(*exec.ExitError); ok {
- if exiterr.ExitCode() == constant.DAEMON_EXIT_CODE {
- logs.Warnf("exit code %d daemon exit", constant.DAEMON_EXIT_CODE)
- systemutil.ExitProcess(constant.DAEMON_EXIT_CODE)
+ if exiterr.ExitCode() == constant.DaemonExitCode {
+ logs.Warnf("exit code %d daemon exit", constant.DaemonExitCode)
+ systemutil.ExitProcess(constant.DaemonExitCode)
}
}
- logs.Error("agent process error", err)
+ logs.WithError(err).Error("agent process error")
if errstd != nil {
return
}
defer stdErr.Close()
out, err := io.ReadAll(stdErr)
if err != nil {
- logs.Error("read agent stderr out error", err)
+ logs.WithError(err).Error("read agent stderr out error")
return
}
logs.Error("agent process error out", string(out))
diff --git a/src/agent/agent/src/cmd/daemon/main_win.go b/src/agent/agent/src/cmd/daemon/main_win.go
index f57da577b28..5e0b710a6be 100644
--- a/src/agent/agent/src/cmd/daemon/main_win.go
+++ b/src/agent/agent/src/cmd/daemon/main_win.go
@@ -31,6 +31,7 @@
package main
import (
+ "errors"
"fmt"
"io"
"os"
@@ -68,8 +69,8 @@ func main() {
}
// 初始化日志
- logFilePath := filepath.Join(systemutil.GetWorkDir(), "logs", "devopsDaemon.log")
- err := logs.Init(logFilePath, isDebug, false)
+ workDir := systemutil.GetExecutableDir()
+ err := logs.Init(filepath.Join(workDir, "logs", "devopsDaemon.log"), isDebug, false)
if err != nil {
fmt.Printf("init daemon log error %v\n", err)
systemutil.ExitProcess(1)
@@ -77,7 +78,6 @@ func main() {
logs.Infof("GOOS=%s, GOARCH=%s", runtime.GOOS, runtime.GOARCH)
- workDir := systemutil.GetExecutableDir()
err = os.Chdir(workDir)
if err != nil {
logs.Info("change work dir failed, err: ", err.Error())
@@ -91,34 +91,31 @@ func main() {
}
}()
+ if ok := systemutil.CheckProcess(daemonProcess); !ok {
+ logs.Info("get process lock failed, exit")
+ return
+ }
+
logs.Info("devops daemon start")
logs.Info("pid: ", os.Getpid())
logs.Info("workDir: ", workDir)
//服务定义
serviceConfig := &service.Config{
- Name: "name",
- DisplayName: "displayName",
- Description: "description",
- WorkingDirectory: "C:/data/landun",
- }
-
- if ok := systemutil.CheckProcess(daemonProcess); !ok {
- logs.Info("get process lock failed, exit")
- return
+ Name: "name",
}
daemonProgram := &program{}
sys := service.ChosenSystem()
daemonService, err := sys.New(daemonProgram, serviceConfig)
if err != nil {
- logs.Error("Init service error: ", err.Error())
+ logs.WithError(err).Error("Init service error")
systemutil.ExitProcess(1)
}
err = daemonService.Run()
if err != nil {
- logs.Error("run agent program error: ", err.Error())
+ logs.WithError(err).Error("run agent program error")
}
}
@@ -128,65 +125,70 @@ func watch() {
workDir := systemutil.GetExecutableDir()
var agentPath = systemutil.GetWorkDir() + "/devopsAgent.exe"
for {
- cmd := exec.Command(agentPath)
- cmd.Dir = workDir
-
- // 获取 agent 的错误输出,这样有助于打印出崩溃的堆栈方便排查问题
- stdErr, errstd := cmd.StderrPipe()
- if errstd != nil {
- logs.Error("get agent stderr pipe error", errstd)
- } else {
- defer stdErr.Close()
- }
-
- logs.Info("start devops agent")
- if !fileutil.Exists(agentPath) {
- logs.Error("agent file: ", agentPath, " not exists")
- logs.Info("restart after 30 seconds")
- time.Sleep(30 * time.Second)
- }
-
- err := fileutil.SetExecutable(agentPath)
- if err != nil {
- logs.Error("chmod failed, err: ", err.Error())
- logs.Info("restart after 30 seconds")
- time.Sleep(30 * time.Second)
- continue
- }
+ func() {
+ cmd := exec.Command(agentPath)
+ cmd.Dir = workDir
- err = cmd.Start()
- if err != nil {
- logs.Error("agent start failed, err: ", err.Error())
- logs.Info("restart after 30 seconds")
- time.Sleep(30 * time.Second)
- continue
- }
+ // 获取 agent 的错误输出,这样有助于打印出崩溃的堆栈方便排查问题
+ stdErr, errstd := cmd.StderrPipe()
+ if errstd != nil {
+ logs.WithError(errstd).Error("get agent stderr pipe error")
+ } else {
+ defer stdErr.Close()
+ }
- GAgentProcess = cmd.Process
- logs.Info("devops agent started, pid: ", cmd.Process.Pid)
- _, err = cmd.Process.Wait()
- if err != nil {
- if exiterr, ok := err.(*exec.ExitError); ok {
- if exiterr.ExitCode() == constant.DAEMON_EXIT_CODE {
- logs.Warnf("exit code %d daemon exit", constant.DAEMON_EXIT_CODE)
- systemutil.ExitProcess(constant.DAEMON_EXIT_CODE)
- }
+ logs.Info("start devops agent")
+ if !fileutil.Exists(agentPath) {
+ logs.Errorf("agent file: %s not exists", agentPath)
+ logs.Info("restart after 30 seconds")
+ time.Sleep(30 * time.Second)
}
- logs.Error("agent process error", err)
- if errstd != nil {
+
+ err := fileutil.SetExecutable(agentPath)
+ if err != nil {
+ logs.WithError(err).Error("chmod failed, err")
+ logs.Info("restart after 30 seconds")
+ time.Sleep(30 * time.Second)
return
}
- out, err := io.ReadAll(stdErr)
+
+ err = cmd.Start()
if err != nil {
- logs.Error("read agent stderr out error", err)
+ logs.WithError(err).Error("agent start failed, err")
+ logs.Info("restart after 30 seconds")
+ time.Sleep(30 * time.Second)
return
}
- logs.Error("agent process error out", string(out))
- }
- logs.Info("agent process exited")
- logs.Info("restart after 30 seconds")
- time.Sleep(30 * time.Second)
+ GAgentProcess = cmd.Process
+ logs.Info("devops agent started, pid: ", cmd.Process.Pid)
+ err = cmd.Wait()
+ if err != nil {
+ var exitErr *exec.ExitError
+ if errors.As(err, &exitErr) {
+ if exitErr.ExitCode() == constant.DaemonExitCode {
+ logs.Warnf("exit code %d daemon exit", constant.DaemonExitCode)
+ systemutil.ExitProcess(constant.DaemonExitCode)
+ }
+ }
+ logs.WithError(err).Error("agent process error")
+
+ // 读取可能的报错
+ if errstd != nil {
+ return
+ }
+ out, err := io.ReadAll(stdErr)
+ if err != nil {
+ logs.WithError(err).Error("read agent stderr out error")
+ } else {
+ logs.Error("agent process error out", string(out))
+ }
+ }
+ logs.Info("agent process exited")
+
+ logs.Info("restart after 30 seconds")
+ time.Sleep(30 * time.Second)
+ }()
}
}
diff --git a/src/agent/agent/src/cmd/installer/main.go b/src/agent/agent/src/cmd/installer/main.go
index cf50314137f..db06be8b92d 100644
--- a/src/agent/agent/src/cmd/installer/main.go
+++ b/src/agent/agent/src/cmd/installer/main.go
@@ -76,7 +76,7 @@ func main() {
if config.ActionInstall == *action {
err := installer.DoInstallAgent()
if err != nil {
- logs.Error("install new agent failed: " + err.Error())
+ logs.WithError(err).Error("install new agent failed")
systemutil.ExitProcess(1)
}
} else if config.ActionUninstall == *action {
diff --git a/src/agent/agent/src/cmd/translation_generator/translation_generator.go b/src/agent/agent/src/cmd/translation_generator/translation_generator.go
index 3baf915f104..8357a3685a1 100644
--- a/src/agent/agent/src/cmd/translation_generator/translation_generator.go
+++ b/src/agent/agent/src/cmd/translation_generator/translation_generator.go
@@ -31,6 +31,7 @@ import (
"bytes"
"encoding/json"
"fmt"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/constant"
"go/format"
"os"
"path/filepath"
@@ -148,14 +149,14 @@ func main() {
src := g.format()
// 写入到 translation.go 文件中
outputName := filepath.Join(workDir, "translation", "translation.go")
- err = os.WriteFile(outputName, src, 0644)
+ err = os.WriteFile(outputName, src, constant.CommonFileModePerm)
if err != nil {
fmt.Fprintf(os.Stderr, "writing output: %s", err)
exit()
}
}
-// 生成器保存分析的状态。 主要用来缓冲 format.Source 的输出。
+// Generator 生成器保存分析的状态。 主要用来缓冲 format.Source 的输出。
type Generator struct {
buf bytes.Buffer // 累计输出
}
diff --git a/src/agent/agent/src/cmd/upgrader/main.go b/src/agent/agent/src/cmd/upgrader/main.go
index fea9f816e20..6e32c99d89b 100644
--- a/src/agent/agent/src/cmd/upgrader/main.go
+++ b/src/agent/agent/src/cmd/upgrader/main.go
@@ -74,7 +74,7 @@ func main() {
if config.ActionUpgrade == *action {
err := upgrader.DoUpgradeAgent()
if err != nil {
- logs.Error("upgrade agent failed: " + err.Error())
+ logs.WithError(err).Error("upgrade agent failed")
systemutil.ExitProcess(1)
}
} else if config.ActionUninstall == *action {
diff --git a/src/agent/agent/src/pkg/agent/agent.go b/src/agent/agent/src/pkg/agent/agent.go
index d72ce2240ea..b980f4d4aa7 100644
--- a/src/agent/agent/src/pkg/agent/agent.go
+++ b/src/agent/agent/src/pkg/agent/agent.go
@@ -51,13 +51,23 @@ func Run(isDebug bool) {
// 初始化国际化
i18n.InitAgentI18n()
+ // 启动 agent,需要等到上报启动成功才能继续
_, err := job.AgentStartup()
if err != nil {
- logs.Warn("agent startup failed: ", err.Error())
+ logs.WithError(err).Error("agent startup failed")
+ for {
+ _, err = job.AgentStartup()
+ if err == nil {
+ break
+ } else {
+ logs.WithError(err).Error("agent startup failed")
+ time.Sleep(5 * time.Second)
+ }
+ }
}
// 数据采集
- go collector.DoAgentCollect()
+ go collector.Collect()
// 定期清理
go cron.CleanJob()
@@ -102,7 +112,7 @@ func doAsk() {
}
if err != nil {
- logs.Error("ask request failed: ", err.Error())
+ logs.WithErrorNoStack(err).Error("ask request failed")
return
}
if result.IsNotOk() {
@@ -122,7 +132,7 @@ func doAsk() {
resp := new(api.AskResp)
err = util.ParseJsonToData(result.Data, &resp)
if err != nil {
- logs.Error("parse ask resp failed: ", err.Error())
+ logs.WithErrorNoStack(err).Error("parse ask resp failed")
return
}
diff --git a/src/agent/agent/src/pkg/agent/ask.go b/src/agent/agent/src/pkg/agent/ask.go
index 3fc95ea2287..b80a0fe4790 100644
--- a/src/agent/agent/src/pkg/agent/ask.go
+++ b/src/agent/agent/src/pkg/agent/ask.go
@@ -53,7 +53,7 @@ func genHeartInfoAndUpgrade(
MasterVersion: config.AgentVersion,
SlaveVersion: config.GAgentEnv.SlaveVersion,
HostName: config.GAgentEnv.HostName,
- AgentIp: config.GAgentEnv.AgentIp,
+ AgentIp: config.GAgentEnv.GetAgentIp(),
ParallelTaskCount: config.GAgentConfig.ParallelTaskCount,
AgentInstallPath: systemutil.GetExecutableDir(),
StartedUser: systemutil.GetCurrentUser().Username,
diff --git a/src/agent/agent/src/pkg/agent/heartbeat.go b/src/agent/agent/src/pkg/agent/heartbeat.go
index df76588e8fa..1b35bbb7a22 100644
--- a/src/agent/agent/src/pkg/agent/heartbeat.go
+++ b/src/agent/agent/src/pkg/agent/heartbeat.go
@@ -85,7 +85,23 @@ func agentHeartbeat(heartbeatResponse *api.AgentHeartbeatResponse) {
}
// agent环境变量
- config.GEnvVars = heartbeatResponse.Envs
+ if heartbeatResponse.Envs != nil {
+ if config.GApiEnvVars.Size() <= 0 {
+ config.GApiEnvVars.SetEnvs(heartbeatResponse.Envs)
+ } else {
+ flag := false
+ config.GApiEnvVars.RangeDo(func(k, v string) bool {
+ if heartbeatResponse.Envs[k] != v {
+ flag = true
+ return false
+ }
+ return true
+ })
+ if flag {
+ config.GApiEnvVars.SetEnvs(heartbeatResponse.Envs)
+ }
+ }
+ }
/*
忽略一些在Windows机器上VPN代理软件所产生的虚拟网卡(有Mac地址)的IP,一般这类IP
@@ -93,8 +109,8 @@ func agentHeartbeat(heartbeatResponse *api.AgentHeartbeatResponse) {
*/
if len(config.GAgentConfig.IgnoreLocalIps) > 0 {
splitIps := util.SplitAndTrimSpace(config.GAgentConfig.IgnoreLocalIps, ",")
- if util.Contains(splitIps, config.GAgentEnv.AgentIp) { // Agent检测到的IP与要忽略的本地VPN IP相同,则更换真正IP
- config.GAgentEnv.AgentIp = systemutil.GetAgentIp(splitIps)
+ if util.Contains(splitIps, config.GAgentEnv.GetAgentIp()) { // Agent检测到的IP与要忽略的本地VPN IP相同,则更换真正IP
+ config.GAgentEnv.SetAgentIp(systemutil.GetAgentIp(splitIps))
}
}
diff --git a/src/agent/agent/src/pkg/api/api.go b/src/agent/agent/src/pkg/api/api.go
index 45a4d8d0396..254d515aee5 100644
--- a/src/agent/agent/src/pkg/api/api.go
+++ b/src/agent/agent/src/pkg/api/api.go
@@ -61,7 +61,7 @@ func AgentStartup() (*httputil.DevopsResult, error) {
startInfo := &ThirdPartyAgentStartInfo{
HostName: config.GAgentEnv.HostName,
- HostIp: config.GAgentEnv.AgentIp,
+ HostIp: config.GAgentEnv.GetAgentIp(),
DetectOs: config.GAgentEnv.OsName,
MasterVersion: config.AgentVersion,
SlaveVersion: config.GAgentEnv.SlaveVersion,
diff --git a/src/agent/agent/src/pkg/api/type.go b/src/agent/agent/src/pkg/api/type.go
index 005b23605f3..f46659fed89 100644
--- a/src/agent/agent/src/pkg/api/type.go
+++ b/src/agent/agent/src/pkg/api/type.go
@@ -85,9 +85,10 @@ type Credential struct {
}
type DockerOptions struct {
- Volumes []string `json:"volumes"`
- Gpus string `json:"gpus"`
- Mounts []string `json:"mounts"`
+ Volumes []string `json:"volumes"`
+ Gpus string `json:"gpus"`
+ Mounts []string `json:"mounts"`
+ Privileged bool `json:"privileged"`
}
type ThirdPartyBuildWithStatus struct {
diff --git a/src/agent/agent/src/pkg/collector/collector.go b/src/agent/agent/src/pkg/collector/collector.go
index 0caf71911d0..dd2e528cae5 100644
--- a/src/agent/agent/src/pkg/collector/collector.go
+++ b/src/agent/agent/src/pkg/collector/collector.go
@@ -31,14 +31,12 @@ import (
"bytes"
"context"
"fmt"
- "os"
+ "github.com/pkg/errors"
"text/template"
"time"
telegrafconf "github.com/TencentBlueKing/bk-ci/agent/src/pkg/collector/telegrafConf"
"github.com/TencentBlueKing/bk-ci/agentcommon/utils/fileutil"
- "github.com/pkg/errors"
-
"github.com/influxdata/telegraf/logger"
"github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/systemutil"
@@ -54,63 +52,80 @@ import (
)
const (
- telegrafConfigFile = "telegraf.conf"
telegrafRelaunchTime = 5 * time.Second
-
- templateKeyAgentId = "###{agentId}###"
- templateKeyAgentSecret = "###{agentSecret}###"
- templateKeyGateway = "###{gateway}###"
- templateKeyTlsCa = "###{tls_ca}###"
- templateKeyProjectId = "###{projectId}###"
- templateKeyHostName = "###{hostName}###"
- templateKeyHostIp = "###{hostIp}###"
- templateBuildType = "###{buildType}###"
+ eBusId = "Collect"
)
-func DoAgentCollect() {
+func Collect() {
+ logs.Debug("do Collect")
+ ipChan := config.EBus.Subscribe(config.IpEvent, eBusId, 1)
+
defer func() {
if err := recover(); err != nil {
logs.Error("agent collect panic: ", err)
}
+ config.EBus.Unsubscribe(config.IpEvent, eBusId)
}()
+ for {
+ ctx, cancel := context.WithCancel(context.Background())
+ go func() {
+ ipData := <-ipChan.DChan
+ logs.Infof("collect ip change data: %s", ipData.Data)
+ cancel()
+ }()
+ doAgentCollect(ctx)
+ }
+}
+
+func doAgentCollect(ctx context.Context) {
if config.GAgentConfig.CollectorOn == false {
logs.Info("agent collector off")
return
}
- if err := writeTelegrafConfig(); err != nil {
- logs.WithError(err).Error("writeTelegrafConfig error")
+ configContent, err := genTelegrafConfig()
+ if err != nil {
+ logs.WithError(err).Error("genTelegrafConfig error")
return
}
+ logs.Debug("generate telegraf config")
+
// 每次重启agent要清理掉无意义的telegraf.log日志,重新记录
logFile := fmt.Sprintf("%s/logs/telegraf.log", systemutil.GetWorkDir())
if fileutil.Exists(logFile) {
_ = fileutil.TryRemoveFile(logFile)
}
- tAgent, err := getTelegrafAgent(
- fmt.Sprintf("%s/%s", systemutil.GetWorkDir(), telegrafConfigFile),
- logFile,
- )
+
+ tAgent, err := getTelegrafAgent(configContent.Bytes(), logFile)
if err != nil {
- logs.Errorf("init telegraf agent failed: %v", err)
+ logs.WithError(err).Error("init telegraf agent failed")
return
}
for {
logs.Info("launch telegraf agent")
- if err = tAgent.Run(context.Background()); err != nil {
- logs.Errorf("telegraf agent exit: %v", err)
+ err = tAgent.Run(ctx)
+ select {
+ case <-ctx.Done():
+ // 上下文被取消需要返回调用方重新获取上下文,不然一直是取消状态
+ logs.Info("telegraf agent ctx done")
+ return
+ default:
+ // 普通的 telegraf 退出直接重新启动即可
+ if err != nil {
+ logs.WithError(err).Error("telegraf agent exit")
+ }
}
time.Sleep(telegrafRelaunchTime)
}
}
-func getTelegrafAgent(configFile, logFile string) (*agent.Agent, error) {
+func getTelegrafAgent(configData []byte, logFile string) (*agent.Agent, error) {
// get a new config and parse configuration from file.
c := telegrafConfig.NewConfig()
- if err := c.LoadConfig(configFile); err != nil {
+ if err := c.LoadConfigData(configData); err != nil {
return nil, err
}
@@ -120,52 +135,52 @@ func getTelegrafAgent(configFile, logFile string) (*agent.Agent, error) {
RotationMaxArchives: -1,
}
- logger.SetupLogging(logConfig)
+ if err := logger.SetupLogging(logConfig); err != nil {
+ return nil, err
+ }
return agent.NewAgent(c)
}
-func writeTelegrafConfig() error {
+func genTelegrafConfig() (*bytes.Buffer, error) {
// 区分 stream 项目使用模板分割,PAC 上线后删除
projectType := "ci"
if strings.HasPrefix(config.GAgentConfig.ProjectId, "git_") {
projectType = "stream"
}
- var content bytes.Buffer
- tmpl, err := template.New("tmpl").Parse(telegrafconf.TelegrafConf)
- if err != nil {
- return errors.Wrap(err, "parse telegraf config template err")
- }
- err = tmpl.Execute(&content, projectType)
- if err != nil {
- return errors.Wrap(err, "execute telegraf config template err")
- }
-
- configContent := strings.Replace(content.String(), templateKeyAgentId, config.GAgentConfig.AgentId, 2)
- configContent = strings.Replace(configContent, templateKeyAgentSecret, config.GAgentConfig.SecretKey, 2)
- configContent = strings.Replace(configContent, templateKeyGateway, buildGateway(config.GAgentConfig.Gateway), 1)
- configContent = strings.Replace(configContent, templateKeyProjectId, config.GAgentConfig.ProjectId, 2)
- configContent = strings.Replace(configContent, templateKeyHostName, config.GAgentEnv.HostName, 1)
- configContent = strings.Replace(configContent, templateKeyHostIp, config.GAgentEnv.AgentIp, 1)
- configContent = strings.Replace(configContent, templateBuildType, config.GAgentConfig.BuildType, 1)
+ tlsCa := ""
if config.UseCert {
- configContent = strings.Replace(configContent, templateKeyTlsCa, `tls_ca = ".cert"`, 1)
- } else {
- configContent = strings.Replace(configContent, templateKeyTlsCa, "", 1)
+ tlsCa = `tls_ca = ".cert"`
}
- err = os.WriteFile(systemutil.GetWorkDir()+"/telegraf.conf", []byte(configContent), 0666)
- if err != nil {
- return errors.Wrap(err, "write telegraf config err")
+ buildGateway := config.GAgentConfig.Gateway
+ if !strings.HasPrefix(buildGateway, "http") {
+ buildGateway = "http://" + buildGateway
}
- return nil
-}
+ ip := config.GAgentEnv.GetAgentIp()
+ templateData := map[string]string{
+ "ProjectType": projectType,
+ "AgentId": config.GAgentConfig.AgentId,
+ "AgentSecret": config.GAgentConfig.SecretKey,
+ "Gateway": buildGateway,
+ "ProjectId": config.GAgentConfig.ProjectId,
+ "HostName": config.GAgentEnv.HostName,
+ "HostIp": config.GAgentEnv.GetAgentIp(),
+ "BuildType": config.GAgentConfig.BuildType,
+ "TlsCa": tlsCa,
+ }
+ logs.Debugf("telegraf agentip %s", ip)
-func buildGateway(gateway string) string {
- if strings.HasPrefix(gateway, "http") {
- return gateway
- } else {
- return "http://" + gateway
+ var content = new(bytes.Buffer)
+ tmpl, err := template.New("tmpl").Parse(telegrafconf.TelegrafConf)
+ if err != nil {
+ return nil, errors.Wrap(err, "parse telegraf config template err")
}
+ err = tmpl.Execute(content, templateData)
+ if err != nil {
+ return nil, errors.Wrap(err, "execute telegraf config template err")
+ }
+
+ return content, nil
}
diff --git a/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf.go b/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf.go
index 1b22dea730b..cb2196defc8 100644
--- a/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf.go
+++ b/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf.go
@@ -32,11 +32,11 @@ package telegrafconf
const TelegrafConf = `
[global_tags]
- projectId = "###{projectId}###"
- agentId = "###{agentId}###"
- agentSecret = "###{agentSecret}###"
- hostName = "###{hostName}###"
- hostIp = "###{hostIp}###"
+ projectId = "{{.ProjectId}}"
+ agentId = "{{.AgentId}}"
+ agentSecret = "{{.AgentSecret}}"
+ hostName = "{{.HostName}}"
+ hostIp = "{{.HostIp}}"
[agent]
interval = "1m"
round_interval = true
@@ -51,12 +51,12 @@ const TelegrafConf = `
logfile = ""
hostname = ""
omit_hostname = false
-{{ if eq . "stream" }}
+{{ if eq .ProjectType "stream" }}
[[outputs.influxdb]]
- urls = ["###{gateway}###/ms/environment/api/buildAgent/agent/thirdPartyAgent/agents/metrix"]
+ urls = ["{{.Gateway}}/ms/environment/api/buildAgent/agent/thirdPartyAgent/agents/metrix"]
database = "agentMetrix"
skip_database_creation = true
- ###{tls_ca}###
+ {{.TlsCa}}
[[inputs.cpu]]
percpu = true
@@ -76,16 +76,16 @@ const TelegrafConf = `
{{ else }}
[[outputs.http]]
- url = "###{gateway}###/ms/environment/api/buildAgent/agent/thirdPartyAgent/agents/metrics"
+ url = "{{.Gateway}}/ms/environment/api/buildAgent/agent/thirdPartyAgent/agents/metrics"
# timeout = "5s"
method = "POST"
data_format = "json"
[outputs.http.headers]
Content-Type = "application/json; charset=utf-8"
- X-DEVOPS-BUILD-TYPE = "###{buildType}###"
- X-DEVOPS-PROJECT-ID = "###{projectId}###"
- X-DEVOPS-AGENT-ID = "###{agentId}###"
- X-DEVOPS-AGENT-SECRET-KEY = "###{agentSecret}###"
+ X-DEVOPS-BUILD-TYPE = "{{.BuildType}}"
+ X-DEVOPS-PROJECT-ID = "{{.ProjectId}}"
+ X-DEVOPS-AGENT-ID = "{{.AgentId}}"
+ X-DEVOPS-AGENT-SECRET-KEY = "{{.AgentSecret}}"
[[inputs.cpu]]
percpu = true
diff --git a/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf_out.go b/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf_out.go
index 4720d05d8e8..4fed292a619 100644
--- a/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf_out.go
+++ b/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf_out.go
@@ -32,9 +32,9 @@ package telegrafconf
const TelegrafConf = `
[global_tags]
- projectId = "###{projectId}###"
- agentId = "###{agentId}###"
- agentSecret = "###{agentSecret}###"
+ projectId = "{{.ProjectId}}"
+ agentId = "{{.AgentId}}"
+ agentSecret = "{{.AgentSecret}}"
[agent]
interval = "1m"
round_interval = true
@@ -50,10 +50,10 @@ const TelegrafConf = `
hostname = ""
omit_hostname = false
[[outputs.influxdb]]
- urls = ["###{gateway}###/ms/environment/api/buildAgent/agent/thirdPartyAgent/agents/metrix"]
+ urls = ["{{.Gateway}}/ms/environment/api/buildAgent/agent/thirdPartyAgent/agents/metrix"]
database = "agentMetrix"
skip_database_creation = true
- ###{tls_ca}###
+ {{.TlsCa}}
[[inputs.cpu]]
percpu = true
totalcpu = true
diff --git a/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf_out_win.go b/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf_out_win.go
index 44cd08c47d3..22a180d9aaf 100644
--- a/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf_out_win.go
+++ b/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf_out_win.go
@@ -32,9 +32,9 @@ package telegrafconf
const TelegrafConf = `
[global_tags]
- projectId = "###{projectId}###"
- agentId = "###{agentId}###"
- agentSecret = "###{agentSecret}###"
+ projectId = "{{.ProjectId}}"
+ agentId = "{{.AgentId}}"
+ agentSecret = "{{.AgentSecret}}"
[agent]
interval = "1m"
round_interval = true
@@ -50,10 +50,10 @@ const TelegrafConf = `
hostname = ""
omit_hostname = false
[[outputs.influxdb]]
- urls = ["###{gateway}###/ms/environment/api/buildAgent/agent/thirdPartyAgent/agents/metrix"]
+ urls = ["{{.Gateway}}/ms/environment/api/buildAgent/agent/thirdPartyAgent/agents/metrix"]
database = "agentMetrix"
skip_database_creation = true
- ###{tls_ca}###
+ {{.TlsCa}}
[[inputs.mem]]
[[inputs.disk]]
ignore_fs = ["tmpfs", "devtmpfs", "devfs", "overlay", "aufs", "squashfs"]
diff --git a/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf_win.go b/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf_win.go
index d24b36672c1..187c9a7eff0 100644
--- a/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf_win.go
+++ b/src/agent/agent/src/pkg/collector/telegrafConf/telegrafConf_win.go
@@ -32,11 +32,11 @@ package telegrafconf
const TelegrafConf = `
[global_tags]
- projectId = "###{projectId}###"
- agentId = "###{agentId}###"
- agentSecret = "###{agentSecret}###"
- hostName = "###{hostName}###"
- hostIp = "###{hostIp}###"
+ projectId = "{{.ProjectId}}"
+ agentId = "{{.AgentId}}"
+ agentSecret = "{{.AgentSecret}}"
+ hostName = "{{.HostName}}"
+ hostIp = "{{.HostIp}}"
[agent]
interval = "1m"
round_interval = true
@@ -51,12 +51,12 @@ const TelegrafConf = `
logfile = ""
hostname = ""
omit_hostname = false
-{{ if eq . "stream" }}
+{{ if eq .ProjectType "stream" }}
[[outputs.influxdb]]
- urls = ["###{gateway}###/ms/environment/api/buildAgent/agent/thirdPartyAgent/agents/metrix"]
+ urls = ["{{.Gateway}}/ms/environment/api/buildAgent/agent/thirdPartyAgent/agents/metrix"]
database = "agentMetrix"
skip_database_creation = true
- ###{tls_ca}###
+ {{.TlsCa}}
[[inputs.mem]]
[[inputs.disk]]
@@ -154,16 +154,16 @@ const TelegrafConf = `
{{ else }}
[[outputs.http]]
- url = "###{gateway}###/ms/environment/api/buildAgent/agent/thirdPartyAgent/agents/metrics"
+ url = "{{.Gateway}}/ms/environment/api/buildAgent/agent/thirdPartyAgent/agents/metrics"
# timeout = "5s"
method = "POST"
data_format = "json"
[outputs.http.headers]
Content-Type = "application/json; charset=utf-8"
- X-DEVOPS-BUILD-TYPE = "###{buildType}###"
- X-DEVOPS-PROJECT-ID = "###{projectId}###"
- X-DEVOPS-AGENT-ID = "###{agentId}###"
- X-DEVOPS-AGENT-SECRET-KEY = "###{agentSecret}###"
+ X-DEVOPS-BUILD-TYPE = "{{.BuildType}}"
+ X-DEVOPS-PROJECT-ID = "{{.ProjectId}}"
+ X-DEVOPS-AGENT-ID = "{{.AgentId}}"
+ X-DEVOPS-AGENT-SECRET-KEY = "{{.AgentSecret}}"
[[inputs.win_perf_counters]]
[[inputs.win_perf_counters.object]]
diff --git a/src/agent/agent/src/pkg/config/bus.go b/src/agent/agent/src/pkg/config/bus.go
new file mode 100644
index 00000000000..60b781d31b9
--- /dev/null
+++ b/src/agent/agent/src/pkg/config/bus.go
@@ -0,0 +1,92 @@
+package config
+
+import (
+ "github.com/TencentBlueKing/bk-ci/agentcommon/logs"
+ "sync"
+)
+
+type DataEvent struct {
+ Data any
+ Topic DataEventType
+}
+
+type DataEventType string
+
+const (
+ IpEvent DataEventType = "IP"
+)
+
+// DataChannel 是一个能接收 DataEvent 的 channel
+type DataChannel struct {
+ Id string
+ DChan chan DataEvent
+}
+
+// EventBus 存储有关订阅者感兴趣的特定主题的信息
+type EventBus struct {
+ subscribers map[DataEventType][]DataChannel
+ rwLock sync.RWMutex
+}
+
+func (eb *EventBus) Publish(topic DataEventType, data any) {
+ go func() {
+ eb.rwLock.RLock()
+ logs.Infof("EventBus Publish %s %v", topic, data)
+ defer eb.rwLock.RUnlock()
+
+ if chs, found := eb.subscribers[topic]; found {
+ for _, ch := range chs {
+ select {
+ case ch.DChan <- DataEvent{Data: data, Topic: topic}:
+ logs.Debugf("EventBus Publish send %s %v", topic, data)
+ default:
+ // 管道满了需要丢弃后写入不然会阻塞
+ <-ch.DChan
+ ch.DChan <- DataEvent{Data: data, Topic: topic}
+ }
+
+ }
+ }
+ logs.Debugf("EventBus Publish send over %s %v", topic, data)
+ }()
+}
+
+func (eb *EventBus) Subscribe(topic DataEventType, id string, chanBuffer int) DataChannel {
+ ch := DataChannel{
+ Id: id,
+ DChan: make(chan DataEvent, chanBuffer),
+ }
+ eb.rwLock.Lock()
+ logs.Infof("EventBus Subscribe %s %s", topic, ch.Id)
+ defer eb.rwLock.Unlock()
+ if prev, found := eb.subscribers[topic]; found {
+ eb.subscribers[topic] = append(prev, ch)
+ } else {
+ eb.subscribers[topic] = append([]DataChannel{}, ch)
+ }
+
+ return ch
+}
+
+func (eb *EventBus) Unsubscribe(topic DataEventType, id string) {
+ eb.rwLock.Lock()
+ logs.Infof("EventBus Unsubscribe %s %s", topic, id)
+ defer eb.rwLock.Unlock()
+ slice := eb.subscribers[topic]
+ for index, ch := range slice {
+ if ch.Id == id {
+ logs.Debugf("EventBus Unsubscribe close %s %s", topic, ch.Id)
+ close(ch.DChan)
+ eb.subscribers[topic] = append(slice[:index], slice[index+1:]...)
+ break
+ }
+ }
+}
+
+var EBus *EventBus
+
+func init() {
+ EBus = &EventBus{
+ subscribers: map[DataEventType][]DataChannel{},
+ }
+}
diff --git a/src/agent/agent/src/pkg/config/bus_test.go b/src/agent/agent/src/pkg/config/bus_test.go
new file mode 100644
index 00000000000..a84b5ed2cbd
--- /dev/null
+++ b/src/agent/agent/src/pkg/config/bus_test.go
@@ -0,0 +1,50 @@
+package config
+
+import (
+ "bytes"
+ "github.com/TencentBlueKing/bk-ci/agentcommon/logs"
+ "strconv"
+ "sync"
+ "testing"
+ "time"
+)
+
+func TestEventBus(t *testing.T) {
+ logs.UNTestDebugInit()
+ wg := sync.WaitGroup{}
+ wg.Add(1)
+ go func() {
+ time.Sleep(3 * time.Second)
+ ipChan := EBus.Subscribe(IpEvent, "go1", 1)
+
+ defer func() {
+ if err := recover(); err != nil {
+ logs.Error("agent collect panic: ", err)
+ }
+ EBus.Unsubscribe(IpEvent, "go1")
+ wg.Done()
+ }()
+
+ data := <-ipChan.DChan
+ if data.Data != "127.0.0.1" {
+ t.Errorf("Subscribe error data is %s", data.Data)
+ }
+ time.Sleep(3 * time.Second)
+
+ var b *bytes.Buffer
+ b.Bytes()
+ }()
+
+ time.Sleep(1 * time.Second)
+ EBus.Publish(IpEvent, "127.0.0.2")
+ time.Sleep(3 * time.Second)
+ EBus.Publish(IpEvent, "127.0.0.1")
+ for i := 3; i <= 8; i++ {
+ time.Sleep(1 * time.Second)
+ EBus.Publish(IpEvent, "127.0.0."+strconv.Itoa(i))
+ }
+ wg.Wait()
+ if len(EBus.subscribers[IpEvent]) > 0 {
+ t.Error("unsubscribe error")
+ }
+}
diff --git a/src/agent/agent/src/pkg/config/config.go b/src/agent/agent/src/pkg/config/config.go
index b054d43d36d..ee6ba743c94 100644
--- a/src/agent/agent/src/pkg/config/config.go
+++ b/src/agent/agent/src/pkg/config/config.go
@@ -31,8 +31,8 @@ import (
"bytes"
"crypto/tls"
"crypto/x509"
- "errors"
"fmt"
+ "github.com/pkg/errors"
"net/http"
"os"
"path/filepath"
@@ -105,30 +105,45 @@ type AgentConfig struct {
// AgentEnv Agent 环境配置
type AgentEnv struct {
OsName string
- AgentIp string
+ agentIp string
HostName string
SlaveVersion string
AgentVersion string
AgentInstallPath string
}
+func (e *AgentEnv) GetAgentIp() string {
+ return e.agentIp
+}
+
+func (e *AgentEnv) SetAgentIp(ip string) {
+ // IP变更时发送事件
+ if e.agentIp != "" && e.agentIp != ip && ip != "127.0.0.1" {
+ EBus.Publish(IpEvent, ip)
+ }
+ e.agentIp = ip
+}
+
var GAgentEnv *AgentEnv
var GAgentConfig *AgentConfig
-var GEnvVars map[string]string
var UseCert bool
-
-var IsDebug bool = false
+var IsDebug = false
// Init 加载和初始化配置
func Init(isDebug bool) {
IsDebug = isDebug
err := LoadAgentConfig()
if err != nil {
- logs.Error("load agent config err: ", err)
+ logs.WithError(err).Error("load agent config err")
systemutil.ExitProcess(1)
}
initCert()
LoadAgentEnv()
+
+ GApiEnvVars = &GEnvVarsT{
+ envs: make(map[string]string),
+ lock: sync.RWMutex{},
+ }
}
// LoadAgentEnv 加载Agent环境
@@ -139,12 +154,11 @@ func LoadAgentEnv() {
忽略一些在Windows机器上VPN代理软件所产生的虚拟网卡(有Mac地址)的IP,一般这类IP
更像是一些路由器的192开头的IP,属于干扰IP,安装了这类软件的windows机器IP都会变成相同,所以需要忽略掉
*/
+ var splitIps []string
if len(GAgentConfig.IgnoreLocalIps) > 0 {
- splitIps := util.SplitAndTrimSpace(GAgentConfig.IgnoreLocalIps, ",")
- GAgentEnv.AgentIp = systemutil.GetAgentIp(splitIps)
- } else {
- GAgentEnv.AgentIp = systemutil.GetAgentIp([]string{})
+ splitIps = util.SplitAndTrimSpace(GAgentConfig.IgnoreLocalIps, ",")
}
+ GAgentEnv.SetAgentIp(systemutil.GetAgentIp(splitIps))
GAgentEnv.HostName = systemutil.GetHostName()
GAgentEnv.OsName = systemutil.GetOsName()
@@ -168,7 +182,7 @@ func DetectAgentVersionByDir(workDir string) string {
}
err := fileutil.SetExecutable(agentExecutable)
if err != nil {
- logs.Warn(fmt.Errorf("chmod agent file failed: %v", err))
+ logs.WithError(err).Warn("chmod agent file failed")
return ""
}
}
diff --git a/src/agent/agent/src/pkg/config/env.go b/src/agent/agent/src/pkg/config/env.go
new file mode 100644
index 00000000000..494071c552e
--- /dev/null
+++ b/src/agent/agent/src/pkg/config/env.go
@@ -0,0 +1,75 @@
+package config
+
+import (
+ "os"
+ "strings"
+ "sync"
+)
+
+// GApiEnvVars 来自页面配置的环境变量
+var GApiEnvVars *GEnvVarsT
+
+type GEnvVarsT struct {
+ envs map[string]string
+ lock sync.RWMutex
+}
+
+func (e *GEnvVarsT) Get(key string) (string, bool) {
+ e.lock.RLock()
+ defer e.lock.RUnlock()
+ res, ok := e.envs[key]
+ return res, ok
+}
+
+func (e *GEnvVarsT) SetEnvs(envs map[string]string) {
+ e.lock.Lock()
+ defer e.lock.Unlock()
+ e.envs = envs
+}
+
+func (e *GEnvVarsT) RangeDo(do func(k, v string) bool) {
+ e.lock.RLock()
+ defer e.lock.RUnlock()
+ for k, v := range e.envs {
+ ok := do(k, v)
+ if !ok {
+ return
+ }
+ }
+}
+
+func (e *GEnvVarsT) Size() int {
+ e.lock.RLock()
+ defer e.lock.RUnlock()
+ return len(e.envs)
+}
+
+// FetchEnvAndCheck 查询是否有某个环境变量,同时校验是否符合要求
+func FetchEnvAndCheck(key string, checkValue string) bool {
+ v, ok := FetchEnv(key)
+ if !ok {
+ return checkValue == ""
+ }
+ return v == checkValue
+}
+
+// FetchEnv 查询是否有某个环境变量,需要同时查询系统和后台变量
+func FetchEnv(key string) (string, bool) {
+ // 优先使用后台配置的
+ v, ok := GApiEnvVars.Get(key)
+ if ok {
+ return v, true
+ }
+
+ for _, envStr := range os.Environ() {
+ parts := strings.Split(envStr, "=")
+ if len(parts) < 2 {
+ continue
+ }
+ if parts[0] == key {
+ return parts[1], true
+ }
+ }
+
+ return "", false
+}
diff --git a/src/agent/agent/src/pkg/constant/constant.go b/src/agent/agent/src/pkg/constant/constant.go
index 4e24909a71d..f3f591ec326 100644
--- a/src/agent/agent/src/pkg/constant/constant.go
+++ b/src/agent/agent/src/pkg/constant/constant.go
@@ -1,6 +1,3 @@
-//go:build !out
-// +build !out
-
/*
* Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
*
@@ -30,9 +27,19 @@
package constant
-// 用来放一些常量,可能内外部不一致
+import "os"
const (
- DockerDataDir = "/data/landun/workspace"
- DAEMON_EXIT_CODE = 88
+ DaemonExitCode = 88
+
+ // DevopsAgentEnableNewConsole 如果设为true 则windows启动进程时使用 newConsole
+ DevopsAgentEnableNewConsole = "DEVOPS_AGENT_ENABLE_NEW_CONSOLE"
+ // DevopsAgentEnableExitGroup 启动Agent杀掉构建进程组的兜底逻辑
+ DevopsAgentEnableExitGroup = "DEVOPS_AGENT_ENABLE_EXIT_GROUP"
+
+ // CommonFileModePerm 公共文件权限
+ CommonFileModePerm os.FileMode = 0644
+
+ // WinCommandNewConsole windwos启动进程时打开新的console窗口
+ WinCommandNewConsole = 0x00000010
)
diff --git a/src/agent/agent/src/pkg/constant/constant_inner.go b/src/agent/agent/src/pkg/constant/constant_inner.go
new file mode 100644
index 00000000000..3ae322273dc
--- /dev/null
+++ b/src/agent/agent/src/pkg/constant/constant_inner.go
@@ -0,0 +1,37 @@
+//go:build !out
+// +build !out
+
+/*
+ * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.
+ *
+ * A copy of the MIT License is included in this file.
+ *
+ *
+ * Terms of the MIT License:
+ * ---------------------------------------------------
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+ * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package constant
+
+// 用来放一些常量,可能内外部不一致
+
+const (
+ DockerDataDir = "/data/landun/workspace"
+)
diff --git a/src/agent/agent/src/pkg/constant/constant_out.go b/src/agent/agent/src/pkg/constant/constant_out.go
index 412d636e906..2600a5b10bf 100644
--- a/src/agent/agent/src/pkg/constant/constant_out.go
+++ b/src/agent/agent/src/pkg/constant/constant_out.go
@@ -33,6 +33,5 @@ package constant
// 用来放一些常量,可能内外部不一致
const (
- DockerDataDir = "/data/devops/workspace"
- DAEMON_EXIT_CODE = 88
+ DockerDataDir = "/data/devops/workspace"
)
diff --git a/src/agent/agent/src/pkg/cron/cron.go b/src/agent/agent/src/pkg/cron/cron.go
index 0ab74ab260b..c904810b3a4 100644
--- a/src/agent/agent/src/pkg/cron/cron.go
+++ b/src/agent/agent/src/pkg/cron/cron.go
@@ -145,7 +145,7 @@ func cleanLogFile(timeBeforeInHours int) {
}
dockerFiles, err := os.ReadDir(dockerLogDir)
if err != nil {
- logs.Error("read docker log dir error: ", err.Error())
+ logs.WithError(err).Error("read docker log dir error")
return
}
diff --git a/src/agent/agent/src/pkg/exiterror/exiterror.go b/src/agent/agent/src/pkg/exiterror/exiterror.go
index f2a0251bead..d7ffa49df37 100644
--- a/src/agent/agent/src/pkg/exiterror/exiterror.go
+++ b/src/agent/agent/src/pkg/exiterror/exiterror.go
@@ -1,8 +1,8 @@
package exitcode
import (
- "errors"
"fmt"
+ "github.com/pkg/errors"
"os"
"strings"
"sync/atomic"
@@ -47,7 +47,7 @@ func Exit(exitError *ExitErrorType) {
if exitError != nil {
logs.Errorf("ExitError|%s|%s", exitError.ErrorEnum, exitError.Message)
}
- os.Exit(constant.DAEMON_EXIT_CODE)
+ os.Exit(constant.DaemonExitCode)
}
func WriteFileWithCheck(name string, data []byte, perm os.FileMode) error {
@@ -80,7 +80,7 @@ func CheckOsIoError(path string, err error) {
}
// 避免不必要的错杀,信号错误最少连续持续 10 次以上才能杀掉
-var jdkSignFlag atomic.Int32 = atomic.Int32{}
+var jdkSignFlag = atomic.Int32{}
func CheckSignalJdkError(err error) {
if err == nil {
@@ -110,7 +110,7 @@ func CheckSignalJdkError(err error) {
}
}
-var workerSignFlag atomic.Int32 = atomic.Int32{}
+var workerSignFlag = atomic.Int32{}
func CheckSignalWorkerError(err error) {
if err == nil {
diff --git a/src/agent/agent/src/pkg/imagedebug/imagedebug.go b/src/agent/agent/src/pkg/imagedebug/imagedebug.go
index 4d61bcc552d..42241c4dfbc 100644
--- a/src/agent/agent/src/pkg/imagedebug/imagedebug.go
+++ b/src/agent/agent/src/pkg/imagedebug/imagedebug.go
@@ -227,7 +227,7 @@ func CreateDebugContainer(
RegistryAuth: auth,
})
if err != nil {
- imageDebugLogs.Errorf("pull new image %s error %s", imageName, err.Error())
+ imageDebugLogs.WithError(err).Errorf("pull new image %s error", imageName)
return errors.New(i18n.Localize("PullImageError", map[string]interface{}{"name": imageName, "err": err.Error()}))
}
defer reader.Close()
@@ -245,7 +245,7 @@ func CreateDebugContainer(
}
// 解析docker options
- dockerConfig, err := job_docker.ParseDockeroptions(cli, debugInfo.Options)
+ dockerConfig, err := job_docker.ParseDockerOptions(cli, debugInfo.Options)
if err != nil {
imageDebugLogs.Error(err.Error())
return err
@@ -515,7 +515,7 @@ func CreateExecServer(
Cmd: conf.Cmd,
})
- url := fmt.Sprintf("ws://%s:%d/start_exec?exec_id=%s&container_id=%s", config.GAgentEnv.AgentIp, conf.Port, exec.ID, containerId)
+ url := fmt.Sprintf("ws://%s:%d/start_exec?exec_id=%s&container_id=%s", config.GAgentEnv.GetAgentIp(), conf.Port, exec.ID, containerId)
// 上报结束并附带 url
imageDebugLogs.Infof("ws url: %s", url)
diff --git a/src/agent/agent/src/pkg/imagedebug/manager.go b/src/agent/agent/src/pkg/imagedebug/manager.go
index ab5a4e83ca7..db095a4c852 100644
--- a/src/agent/agent/src/pkg/imagedebug/manager.go
+++ b/src/agent/agent/src/pkg/imagedebug/manager.go
@@ -30,7 +30,7 @@ type Manager interface {
Start() error
CreateExecNoHttp(*WebSocketConfig) (*docker.Exec, error)
- // handler container web console
+ // StartExec handler container web console
StartExec(http.ResponseWriter, *http.Request, *WebSocketConfig)
CreateExec(http.ResponseWriter, *http.Request, *WebSocketConfig)
ResizeExec(http.ResponseWriter, *http.Request, *WebSocketConfig)
diff --git a/src/agent/agent/src/pkg/installer/installer.go b/src/agent/agent/src/pkg/installer/installer.go
index d27b0e58803..f3a069c8a35 100644
--- a/src/agent/agent/src/pkg/installer/installer.go
+++ b/src/agent/agent/src/pkg/installer/installer.go
@@ -28,8 +28,8 @@
package installer
import (
- "errors"
"fmt"
+ "github.com/pkg/errors"
"github.com/TencentBlueKing/bk-ci/agentcommon/logs"
@@ -53,7 +53,7 @@ func DoInstallAgent() error {
totalLock := flock.New(fmt.Sprintf("%s/%s.lock", systemutil.GetRuntimeDir(), systemutil.TotalLock))
err := totalLock.Lock()
if err = totalLock.Lock(); err != nil {
- logs.Error("get total lock failed, exit", err.Error())
+ logs.WithError(err).Error("get total lock failed, exit")
return errors.New("get total lock failed")
}
defer func() { totalLock.Unlock() }()
@@ -125,7 +125,7 @@ func InstallAgent() error {
err := fileutil.SetExecutable(startCmd)
if err != nil {
- return fmt.Errorf("chmod install script failed: %s", err.Error())
+ return errors.Wrap(err, "chmod install script failed")
}
output, err := command.RunCommand(startCmd, []string{} /*args*/, workDir, nil)
diff --git a/src/agent/agent/src/pkg/job/build.go b/src/agent/agent/src/pkg/job/build.go
index 31c33a32fb2..b632ef86daf 100644
--- a/src/agent/agent/src/pkg/job/build.go
+++ b/src/agent/agent/src/pkg/job/build.go
@@ -30,8 +30,8 @@ package job
import (
"encoding/base64"
"encoding/json"
- "errors"
"fmt"
+ "github.com/pkg/errors"
"io/fs"
"os"
"strings"
@@ -44,7 +44,6 @@ import (
"github.com/TencentBlueKing/bk-ci/agent/src/pkg/config"
exitcode "github.com/TencentBlueKing/bk-ci/agent/src/pkg/exiterror"
"github.com/TencentBlueKing/bk-ci/agent/src/pkg/i18n"
- "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/command"
"github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/httputil"
"github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/systemutil"
"github.com/TencentBlueKing/bk-ci/agentcommon/utils/fileutil"
@@ -61,8 +60,6 @@ func init() {
BuildTotalManager = new(BuildTotalManagerType)
}
-const buildIntervalInSeconds = 5
-
// AgentStartup 上报构建机启动
func AgentStartup() (agentStatus string, err error) {
result, err := api.AgentStartup()
@@ -72,7 +69,7 @@ func AgentStartup() (agentStatus string, err error) {
// parseAgentStatusResult 解析状态信息
func parseAgentStatusResult(result *httputil.DevopsResult, resultErr error) (agentStatus string, err error) {
if resultErr != nil {
- logs.Error("parse agent status error: ", resultErr.Error())
+ logs.WithErrorNoStack(resultErr).Error("parse agent status error")
return "", errors.New("parse agent status error")
}
if result.IsNotOk() {
@@ -131,11 +128,11 @@ func DoBuild(buildInfo *api.ThirdPartyBuildInfo) {
err := runBuild(buildInfo)
if err != nil {
- logs.Error("start build failed: ", err.Error())
+ logs.WithError(err).Error("start build failed")
}
}
-// checkParallelTaskCount 检查当前运行的最大任务数
+// CheckParallelTaskCount checkParallelTaskCount 检查当前运行的最大任务数
func CheckParallelTaskCount() (dockerCanRun bool, normalCanRun bool) {
// 检查docker任务
dockerInstanceCount := GBuildDockerManager.GetInstanceCount()
@@ -211,10 +208,11 @@ func runBuild(buildInfo *api.ThirdPartyBuildInfo) error {
"DEVOPS_GATEWAY": config.GetGateWay(),
"BK_CI_LOCALE_LANGUAGE": config.GAgentConfig.Language,
}
- if config.GEnvVars != nil {
- for k, v := range config.GEnvVars {
+ if config.GApiEnvVars != nil {
+ config.GApiEnvVars.RangeDo(func(k, v string) bool {
goEnv[k] = v
- }
+ return true
+ })
}
// #5806 定义临时目录
tmpDir, tmpMkErr := systemutil.MkBuildTmpDir()
@@ -224,50 +222,11 @@ func runBuild(buildInfo *api.ThirdPartyBuildInfo) error {
workerBuildFinish(buildInfo.ToFinish(false, errMsg, api.MakeTmpDirErrorEnum))
return tmpMkErr
}
- if systemutil.IsWindows() {
- startCmd := config.GetJava()
- agentLogPrefix := fmt.Sprintf("%s_%s_agent", buildInfo.BuildId, buildInfo.VmSeqId)
- errorMsgFile := getWorkerErrorMsgFile(buildInfo.BuildId, buildInfo.VmSeqId)
- args := []string{
- "-Djava.io.tmpdir=" + tmpDir,
- "-Ddevops.agent.error.file=" + errorMsgFile,
- "-Dbuild.type=AGENT",
- "-DAGENT_LOG_PREFIX=" + agentLogPrefix,
- "-Xmx2g", // #5806 兼容性问题,必须独立一行
- "-jar",
- config.BuildAgentJarPath(),
- getEncodedBuildInfo(buildInfo)}
- pid, err := command.StartProcess(startCmd, args, workDir, goEnv, runUser)
- if err != nil {
- errMsg := i18n.Localize("StartWorkerProcessFailed", map[string]interface{}{"err": err.Error()})
- logs.Error(errMsg)
- workerBuildFinish(buildInfo.ToFinish(false, errMsg, api.BuildProcessStartErrorEnum))
- return err
- }
- // 添加需要构建结束后删除的文件
- buildInfo.ToDelTmpFiles = []string{errorMsgFile}
- GBuildManager.AddBuild(pid, buildInfo)
- logs.Info(fmt.Sprintf("[%s]|Job#_%s|Build started, pid:%d ", buildInfo.BuildId, buildInfo.VmSeqId, pid))
- return nil
- } else {
- startScriptFile, err := writeStartBuildAgentScript(buildInfo, tmpDir)
- if err != nil {
- errMsg := i18n.Localize("CreateStartScriptFailed", map[string]interface{}{"err": err.Error()})
- logs.Error(errMsg)
- workerBuildFinish(buildInfo.ToFinish(false, errMsg, api.PrepareScriptCreateErrorEnum))
- return err
- }
- pid, err := command.StartProcess(startScriptFile, []string{}, workDir, goEnv, runUser)
- if err != nil {
- errMsg := i18n.Localize("StartWorkerProcessFailed", map[string]interface{}{"err": err.Error()})
- logs.Error(errMsg)
- workerBuildFinish(buildInfo.ToFinish(false, errMsg, api.BuildProcessStartErrorEnum))
- return err
- }
- GBuildManager.AddBuild(pid, buildInfo)
- logs.Info(fmt.Sprintf("[%s]|Job#_%s|Build started, pid:%d ", buildInfo.BuildId, buildInfo.VmSeqId, pid))
+ if err := doBuild(buildInfo, tmpDir, workDir, goEnv, runUser); err != nil {
+ return err
}
+
return nil
}
@@ -279,71 +238,6 @@ func getEncodedBuildInfo(buildInfo *api.ThirdPartyBuildInfo) string {
return codedBuildInfo
}
-func writeStartBuildAgentScript(buildInfo *api.ThirdPartyBuildInfo, tmpDir string) (string, error) {
- logs.Info("write start build agent script to file")
- // 套娃,多加一层脚本,使用exec新起进程,这样才会读取 .bash_profile
- prepareScriptFile := fmt.Sprintf(
- "%s/devops_agent_prepare_start_%s_%s_%s.sh",
- systemutil.GetWorkDir(), buildInfo.ProjectId, buildInfo.BuildId, buildInfo.VmSeqId)
- scriptFile := fmt.Sprintf(
- "%s/devops_agent_start_%s_%s_%s.sh",
- systemutil.GetWorkDir(), buildInfo.ProjectId, buildInfo.BuildId, buildInfo.VmSeqId)
-
- errorMsgFile := getWorkerErrorMsgFile(buildInfo.BuildId, buildInfo.VmSeqId)
- buildInfo.ToDelTmpFiles = []string{
- scriptFile, prepareScriptFile, errorMsgFile,
- }
-
- logs.Info("start agent script: ", scriptFile)
- agentLogPrefix := fmt.Sprintf("%s_%s_agent", buildInfo.BuildId, buildInfo.VmSeqId)
- lines := []string{
- "#!" + getCurrentShell(),
- fmt.Sprintf("cd %s", systemutil.GetWorkDir()),
- fmt.Sprintf("%s -Ddevops.slave.agent.start.file=%s -Ddevops.slave.agent.prepare.start.file=%s "+
- "-Ddevops.agent.error.file=%s "+
- "-Dbuild.type=AGENT -DAGENT_LOG_PREFIX=%s -Xmx2g -Djava.io.tmpdir=%s -jar %s %s",
- config.GetJava(), scriptFile, prepareScriptFile,
- errorMsgFile,
- agentLogPrefix, tmpDir, config.BuildAgentJarPath(), getEncodedBuildInfo(buildInfo)),
- }
- scriptContent := strings.Join(lines, "\n")
-
- err := exitcode.WriteFileWithCheck(scriptFile, []byte(scriptContent), os.ModePerm)
- defer func() {
- _ = systemutil.Chmod(scriptFile, os.ModePerm)
- _ = systemutil.Chmod(prepareScriptFile, os.ModePerm)
- }()
- if err != nil {
- return "", err
- } else {
- prepareScriptContent := strings.Join(getShellLines(scriptFile), "\n")
- err := exitcode.WriteFileWithCheck(prepareScriptFile, []byte(prepareScriptContent), os.ModePerm)
- if err != nil {
- return "", err
- } else {
- return prepareScriptFile, nil
- }
- }
-}
-
-// getShellLines 根据不同的shell的参数要求,这里可能需要不同的参数或者参数顺序
-func getShellLines(scriptFile string) (newLines []string) {
- shell := getCurrentShell()
- switch shell {
- case "/bin/tcsh":
- newLines = []string{
- "#!" + shell,
- "exec " + shell + " " + scriptFile + " -l",
- }
- default:
- newLines = []string{
- "#!" + shell,
- "exec " + shell + " -l " + scriptFile,
- }
- }
- return newLines
-}
-
func workerBuildFinish(buildInfo *api.ThirdPartyBuildWithStatus) {
if buildInfo == nil {
logs.Warn("buildInfo not exist")
@@ -367,7 +261,7 @@ func workerBuildFinish(buildInfo *api.ThirdPartyBuildWithStatus) {
}
result, err := api.WorkerBuildFinish(buildInfo)
if err != nil {
- logs.Error("send worker build finish failed: ", err.Error())
+ logs.WithErrorNoStack(err).Error("send worker build finish failed")
}
if result.IsNotOk() {
logs.Error("send worker build finish failed: ", result.Message)
@@ -428,15 +322,38 @@ func removeFileThan7Days(dir string, f fs.DirEntry) {
}
}
-func getCurrentShell() (shell string) {
- if config.GAgentConfig.DetectShell {
- shell = os.Getenv("SHELL")
- if strings.TrimSpace(shell) == "" {
- shell = "/bin/bash"
- }
- } else {
- shell = "/bin/bash"
+const (
+ errorMsgFileSuffix = "build_msg.log"
+ prepareStartScriptFilePrefix = "devops_agent_prepare_start"
+ prepareStartScriptFileSuffix = ".sh"
+ startScriptFilePrefix = "devops_agent_start"
+ startScriptFileSuffix = ".sh"
+)
+
+// getWorkerErrorMsgFile 获取worker执行错误信息的日志文件
+func getWorkerErrorMsgFile(buildId, vmSeqId string) string {
+ return fmt.Sprintf("%s/build_tmp/%s_%s_%s",
+ systemutil.GetWorkDir(), buildId, vmSeqId, errorMsgFileSuffix)
+}
+
+// getUnixWorkerPrepareStartScriptFile 获取unix系统,主要是darwin和linux的prepare start script文件
+func getUnixWorkerPrepareStartScriptFile(projectId, buildId, vmSeqId string) string {
+ return fmt.Sprintf("%s/%s_%s_%s_%s%s",
+ systemutil.GetWorkDir(), prepareStartScriptFilePrefix, projectId, buildId, vmSeqId, prepareStartScriptFileSuffix)
+}
+
+// getUnixWorkerStartScriptFile 获取unix系统,主要是darwin和linux的prepare start script文件
+func getUnixWorkerStartScriptFile(projectId, buildId, vmSeqId string) string {
+ return fmt.Sprintf("%s/%s_%s_%s_%s%s",
+ systemutil.GetWorkDir(), startScriptFilePrefix, projectId, buildId, vmSeqId, startScriptFileSuffix)
+}
+
+// CheckRunningJob 校验当前是否有正在跑的任务
+func CheckRunningJob() bool {
+ if GBuildManager.GetPreInstancesCount() > 0 ||
+ GBuildManager.GetInstanceCount() > 0 ||
+ GBuildDockerManager.GetInstanceCount() > 0 {
+ return true
}
- logs.Info("current shell: ", shell)
- return
+ return false
}
diff --git a/src/agent/agent/src/pkg/job/build_docker.go b/src/agent/agent/src/pkg/job/build_docker.go
index 340c19bbd6f..3be9fc9b91a 100644
--- a/src/agent/agent/src/pkg/job/build_docker.go
+++ b/src/agent/agent/src/pkg/job/build_docker.go
@@ -30,6 +30,7 @@ package job
import (
"context"
"fmt"
+ "github.com/pkg/errors"
"io"
"os"
"path/filepath"
@@ -52,7 +53,6 @@ import (
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
- "github.com/pkg/errors"
)
// buildDockerManager docker构建机构建对象管理
@@ -160,7 +160,7 @@ func doDockerJob(buildInfo *api.ThirdPartyBuildInfo) {
ctx := context.Background()
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
- logs.Error("DOCKER_JOB|create docker client error ", err)
+ logs.WithError(err).Error("DOCKER_JOB|create docker client error")
dockerBuildFinish(buildInfo.ToFinish(false, i18n.Localize("LinkDockerError", map[string]interface{}{"err": err}), api.DockerClientCreateErrorEnum))
return
}
@@ -170,7 +170,7 @@ func doDockerJob(buildInfo *api.ThirdPartyBuildInfo) {
// 判断本地是否已经有镜像了
images, err := cli.ImageList(ctx, types.ImageListOptions{})
if err != nil {
- logs.Error("DOCKER_JOB|list docker images error ", err)
+ logs.WithError(err).Error("DOCKER_JOB|list docker images error")
dockerBuildFinish(buildInfo.ToFinish(false, i18n.Localize("GetDockerImagesError", map[string]interface{}{"err": err}), api.DockerImagesFetchErrorEnum))
return
}
@@ -212,7 +212,7 @@ func doDockerJob(buildInfo *api.ThirdPartyBuildInfo) {
RegistryAuth: auth,
})
if err != nil {
- logs.Error(fmt.Sprintf("DOCKER_JOB|pull new image %s error ", imageName), err)
+ logs.WithError(err).Errorf("DOCKER_JOB|pull new image %s error", imageName)
dockerBuildFinish(buildInfo.ToFinish(false, i18n.Localize("PullImageError", map[string]interface{}{"name": imageName, "err": err.Error()}), api.DockerImagePullErrorEnum))
return
}
@@ -220,7 +220,7 @@ func doDockerJob(buildInfo *api.ThirdPartyBuildInfo) {
buf := new(strings.Builder)
_, err = io.Copy(buf, reader)
if err != nil {
- logs.Error("DOCKER_JOB|write image message error ", err)
+ logs.WithError(err).Error("DOCKER_JOB|write image message error")
postLog(true, i18n.Localize("GetPullImageLogError", map[string]interface{}{"err": err.Error()}), buildInfo, api.LogtypeLog)
} else {
// 异步打印,防止过大卡住主流程
@@ -241,9 +241,9 @@ func doDockerJob(buildInfo *api.ThirdPartyBuildInfo) {
}
// 解析docker options
- dockerConfig, err := job_docker.ParseDockeroptions(cli, dockerBuildInfo.Options)
+ dockerConfig, err := job_docker.ParseDockerOptions(cli, dockerBuildInfo.Options)
if err != nil {
- logs.Error("DOCKER_JOB|" + err.Error())
+ logs.WithError(err).Error("DOCKER_JOB|")
dockerBuildFinish(buildInfo.ToFinish(false, err.Error(), api.DockerDockerOptionsErrorEnum))
return
}
@@ -253,7 +253,7 @@ func doDockerJob(buildInfo *api.ThirdPartyBuildInfo) {
mounts, err := parseContainerMounts(buildInfo)
if err != nil {
errMsg := i18n.Localize("ReadDockerMountsError", map[string]interface{}{"err": err.Error()})
- logs.Error("DOCKER_JOB| ", err)
+ logs.WithError(err).Error("DOCKER_JOB|")
dockerBuildFinish(buildInfo.ToFinish(false, errMsg, api.DockerMountCreateErrorEnum))
return
}
@@ -293,7 +293,7 @@ func doDockerJob(buildInfo *api.ThirdPartyBuildInfo) {
creatResp, err := cli.ContainerCreate(ctx, confg, hostConfig, netConfig, nil, containerName)
if err != nil {
- logs.Error(fmt.Sprintf("DOCKER_JOB|create container %s error ", containerName), err)
+ logs.WithError(err).Errorf("DOCKER_JOB|create container %s error", containerName)
dockerBuildFinish(buildInfo.ToFinish(
false,
i18n.Localize("CreateContainerError", map[string]interface{}{"name": containerName, "err": err.Error()}),
@@ -308,13 +308,13 @@ func doDockerJob(buildInfo *api.ThirdPartyBuildInfo) {
return
}
if err = cli.ContainerRemove(ctx, creatResp.ID, types.ContainerRemoveOptions{Force: true}); err != nil {
- logs.Error(fmt.Sprintf("DOCKER_JOB|remove container %s error ", creatResp.ID), err)
+ logs.WithError(err).Errorf("DOCKER_JOB|remove container %s error", creatResp.ID)
}
}()
// 启动容器
if err := cli.ContainerStart(ctx, creatResp.ID, types.ContainerStartOptions{}); err != nil {
- logs.Error(fmt.Sprintf("DOCKER_JOB|start container %s error ", creatResp.ID), err)
+ logs.WithError(err).Errorf("DOCKER_JOB|start container %s error", creatResp.ID)
dockerBuildFinish(buildInfo.ToFinish(
false,
i18n.Localize("StartContainerError", map[string]interface{}{"name": containerName, "err": err.Error()}),
@@ -328,7 +328,7 @@ func doDockerJob(buildInfo *api.ThirdPartyBuildInfo) {
select {
case err := <-errCh:
if err != nil {
- logs.Error(fmt.Sprintf("DOCKER_JOB|wait container %s over error ", creatResp.ID), err)
+ logs.WithError(err).Errorf("DOCKER_JOB|wait container %s over error ", creatResp.ID)
dockerBuildFinish(buildInfo.ToFinish(
false,
i18n.Localize("WaitContainerError", map[string]interface{}{"name": containerName, "err": err.Error()}),
@@ -338,7 +338,7 @@ func doDockerJob(buildInfo *api.ThirdPartyBuildInfo) {
}
case status := <-statusCh:
if status.Error != nil {
- logs.Error(fmt.Sprintf("DOCKER_JOB|wait container %s over error ", creatResp.ID), status.Error)
+ logs.Errorf("DOCKER_JOB|wait container %s over error %v", creatResp.ID, status.Error)
dockerBuildFinish(buildInfo.ToFinish(
false,
i18n.Localize("WaitContainerError", map[string]interface{}{"name": containerName, "err": status.Error.Message}),
diff --git a/src/agent/agent/src/pkg/job/build_manager.go b/src/agent/agent/src/pkg/job/build_manager.go
index 8b483e7aca3..3d1e78b6314 100644
--- a/src/agent/agent/src/pkg/job/build_manager.go
+++ b/src/agent/agent/src/pkg/job/build_manager.go
@@ -30,16 +30,12 @@ package job
import (
"encoding/json"
"fmt"
- "os"
"strings"
"sync"
"github.com/TencentBlueKing/bk-ci/agentcommon/logs"
"github.com/TencentBlueKing/bk-ci/agent/src/pkg/api"
- "github.com/TencentBlueKing/bk-ci/agent/src/pkg/i18n"
- "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/systemutil"
- "github.com/TencentBlueKing/bk-ci/agentcommon/utils/fileutil"
)
// buildManager 二进制构建对象管理
@@ -90,54 +86,10 @@ func (b *buildManager) AddBuild(processId int, buildInfo *api.ThirdPartyBuildInf
b.instances.Store(processId, buildInfo)
// 启动构建了就删除preInstance
b.DeletePreInstance(buildInfo.BuildId)
-
- // #5806 预先录入异常信息,在构建进程正常结束时清理掉。如果没清理掉,则说明进程非正常退出,可能被OS或人为杀死
- errorMsgFile := getWorkerErrorMsgFile(buildInfo.BuildId, buildInfo.VmSeqId)
- _ = fileutil.WriteString(errorMsgFile, i18n.Localize("BuilderProcessWasKilled", nil))
- _ = systemutil.Chmod(errorMsgFile, os.ModePerm)
- b.waitProcessDone(processId)
}
-func (b *buildManager) waitProcessDone(processId int) {
- process, err := os.FindProcess(processId)
- inf, ok := b.instances.Load(processId)
- var info *api.ThirdPartyBuildInfo
- if ok {
- info = inf.(*api.ThirdPartyBuildInfo)
- }
- if err != nil {
- errMsg := i18n.Localize("BuildProcessErr", map[string]interface{}{"pid": processId, "err": err.Error()})
- logs.Warn(errMsg)
- b.instances.Delete(processId)
- workerBuildFinish(info.ToFinish(false, errMsg, api.BuildProcessRunErrorEnum))
- return
- }
-
- state, err := process.Wait()
- // #5806 从b-xxxx_build_msg.log 读取错误信息,此信息可由worker-agent.jar写入,用于当异常时能够将信息上报给服务器
- msgFile := getWorkerErrorMsgFile(info.BuildId, info.VmSeqId)
- msg, _ := fileutil.GetString(msgFile)
- logs.Info(fmt.Sprintf("build[%s] pid[%d] finish, state=%v err=%v, msg=%s", info.BuildId, processId, state, err, msg))
-
- if err != nil {
- if len(msg) == 0 {
- msg = err.Error()
- }
- }
- success := true
- if len(msg) == 0 {
- msg = i18n.Localize("WorkerExit", map[string]interface{}{"pid": processId})
- } else {
- success = false
- }
-
- buildInfo := info
+func (b *buildManager) DeleteBuild(processId int) {
b.instances.Delete(processId)
- if success {
- workerBuildFinish(buildInfo.ToFinish(success, msg, api.NoErrorEnum))
- } else {
- workerBuildFinish(buildInfo.ToFinish(success, msg, api.BuildProcessRunErrorEnum))
- }
}
func (b *buildManager) GetPreInstancesCount() int {
diff --git a/src/agent/agent/src/pkg/job/job_test.go b/src/agent/agent/src/pkg/job/build_test.go
similarity index 100%
rename from src/agent/agent/src/pkg/job/job_test.go
rename to src/agent/agent/src/pkg/job/build_test.go
diff --git a/src/agent/agent/src/pkg/job/do_build.go b/src/agent/agent/src/pkg/job/do_build.go
new file mode 100644
index 00000000000..d2cb79afc2f
--- /dev/null
+++ b/src/agent/agent/src/pkg/job/do_build.go
@@ -0,0 +1,269 @@
+//go:build linux || darwin
+// +build linux darwin
+
+/*
+ * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.
+ *
+ * A copy of the MIT License is included in this file.
+ *
+ *
+ * Terms of the MIT License:
+ * ---------------------------------------------------
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+ * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package job
+
+import (
+ "fmt"
+ "github.com/pkg/errors"
+ "os"
+ "os/exec"
+ "runtime"
+ "strings"
+ "syscall"
+
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/api"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/config"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/constant"
+ exitcode "github.com/TencentBlueKing/bk-ci/agent/src/pkg/exiterror"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/i18n"
+ ucommand "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/command"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/systemutil"
+ "github.com/TencentBlueKing/bk-ci/agentcommon/logs"
+ "github.com/TencentBlueKing/bk-ci/agentcommon/utils/fileutil"
+)
+
+func doBuild(
+ buildInfo *api.ThirdPartyBuildInfo,
+ tmpDir string,
+ workDir string,
+ goEnv map[string]string,
+ runUser string,
+) error {
+ startScriptFile, err := writeStartBuildAgentScript(buildInfo, tmpDir)
+ if err != nil {
+ errMsg := i18n.Localize("CreateStartScriptFailed", map[string]interface{}{"err": err.Error()})
+ logs.Error(errMsg)
+ workerBuildFinish(buildInfo.ToFinish(false, errMsg, api.PrepareScriptCreateErrorEnum))
+ return err
+ }
+
+ enableExitGroup := config.FetchEnvAndCheck(constant.DevopsAgentEnableExitGroup, "true") ||
+ (systemutil.IsMacos() && runtime.GOARCH == "arm64")
+ if enableExitGroup {
+ logs.Infof("%s enable exit group", buildInfo.BuildId)
+ }
+ cmd, err := StartProcessCmd(startScriptFile, []string{}, workDir, goEnv, runUser, enableExitGroup)
+ if err != nil {
+ errMsg := i18n.Localize("StartWorkerProcessFailed", map[string]interface{}{"err": err.Error()})
+ logs.Error(errMsg)
+ workerBuildFinish(buildInfo.ToFinish(false, errMsg, api.BuildProcessStartErrorEnum))
+ return err
+ }
+
+ pid := cmd.Process.Pid
+ GBuildManager.AddBuild(pid, buildInfo)
+ logs.Info(fmt.Sprintf("[%s]|Job#_%s|Build started, pid:%d ", buildInfo.BuildId, buildInfo.VmSeqId, pid))
+
+ // #5806 预先录入异常信息,在构建进程正常结束时清理掉。如果没清理掉,则说明进程非正常退出,可能被OS或人为杀死
+ errorMsgFile := getWorkerErrorMsgFile(buildInfo.BuildId, buildInfo.VmSeqId)
+ _ = fileutil.WriteString(errorMsgFile, i18n.Localize("BuilderProcessWasKilled", nil))
+ _ = systemutil.Chmod(errorMsgFile, os.ModePerm)
+
+ if enableExitGroup {
+ pgId, errPg := syscall.Getpgid(pid)
+ if errPg != nil {
+ logs.Errorf("%s %d get pgid error %s", buildInfo.BuildId, pid, errPg.Error())
+ }
+ err = cmd.Wait()
+ if errPg == nil {
+ go func() {
+ logs.Infof("%s do kill %d process group %d", buildInfo.BuildId, pid, pgId)
+ // 杀死进程组
+ errPg = syscall.Kill(-pgId, syscall.SIGKILL)
+ if errPg != nil {
+ logs.Errorf("%s failed to kill %d process group %d : %s", buildInfo.BuildId, pid, pgId, errPg.Error())
+ return
+ }
+ }()
+ }
+ } else {
+ err = cmd.Wait()
+ }
+ // #5806 从b-xxxx_build_msg.log 读取错误信息,此信息可由worker-agent.jar写入,用于当异常时能够将信息上报给服务器
+ msgFile := getWorkerErrorMsgFile(buildInfo.BuildId, buildInfo.VmSeqId)
+ msg, _ := fileutil.GetString(msgFile)
+ if err != nil {
+ logs.Errorf("build[%s] pid[%d] finish, state=%v err=%v, msg=%s", buildInfo.BuildId, pid, cmd.ProcessState, err, msg)
+ } else {
+ logs.Infof("build[%s] pid[%d] finish, state=%v err=%v, msg=%s", buildInfo.BuildId, pid, cmd.ProcessState, err, msg)
+ }
+
+ // #10362 Worker杀掉当前进程父进程导致Agent误报
+ // agent 改动后可能会导致业务执行完成但是进程被杀掉导致流水线错误,所以将错误只是作为额外信息添加
+ cmdErrMsg := ""
+ if err != nil {
+ cmdErrMsg = "|" + err.Error()
+ }
+
+ success := true
+ if len(msg) == 0 {
+ msg = i18n.Localize("WorkerExit", map[string]interface{}{"pid": pid}) + cmdErrMsg
+ } else {
+ msg += cmdErrMsg
+ success = false
+ }
+
+ GBuildManager.DeleteBuild(pid)
+ if success {
+ workerBuildFinish(buildInfo.ToFinish(success, msg, api.NoErrorEnum))
+ } else {
+ workerBuildFinish(buildInfo.ToFinish(success, msg, api.BuildProcessRunErrorEnum))
+ }
+
+ return nil
+}
+
+func writeStartBuildAgentScript(buildInfo *api.ThirdPartyBuildInfo, tmpDir string) (string, error) {
+ logs.Info("write start build agent script to file")
+ // 套娃,多加一层脚本,使用exec新起进程,这样才会读取 .bash_profile
+ prepareScriptFile := fmt.Sprintf(
+ "%s/devops_agent_prepare_start_%s_%s_%s.sh",
+ systemutil.GetWorkDir(), buildInfo.ProjectId, buildInfo.BuildId, buildInfo.VmSeqId)
+ scriptFile := fmt.Sprintf(
+ "%s/devops_agent_start_%s_%s_%s.sh",
+ systemutil.GetWorkDir(), buildInfo.ProjectId, buildInfo.BuildId, buildInfo.VmSeqId)
+
+ errorMsgFile := getWorkerErrorMsgFile(buildInfo.BuildId, buildInfo.VmSeqId)
+ buildInfo.ToDelTmpFiles = []string{
+ scriptFile, prepareScriptFile, errorMsgFile,
+ }
+
+ logs.Info("start agent script: ", scriptFile)
+ agentLogPrefix := fmt.Sprintf("%s_%s_agent", buildInfo.BuildId, buildInfo.VmSeqId)
+ lines := []string{
+ "#!" + getCurrentShell(),
+ fmt.Sprintf("cd %s", systemutil.GetWorkDir()),
+ fmt.Sprintf("%s -Ddevops.slave.agent.start.file=%s -Ddevops.slave.agent.prepare.start.file=%s "+
+ "-Ddevops.agent.error.file=%s "+
+ "-Dbuild.type=AGENT -DAGENT_LOG_PREFIX=%s -Xmx2g -Djava.io.tmpdir=%s -jar %s %s",
+ config.GetJava(), scriptFile, prepareScriptFile,
+ errorMsgFile,
+ agentLogPrefix, tmpDir, config.BuildAgentJarPath(), getEncodedBuildInfo(buildInfo)),
+ }
+ scriptContent := strings.Join(lines, "\n")
+
+ err := exitcode.WriteFileWithCheck(scriptFile, []byte(scriptContent), os.ModePerm)
+ defer func() {
+ _ = systemutil.Chmod(scriptFile, os.ModePerm)
+ _ = systemutil.Chmod(prepareScriptFile, os.ModePerm)
+ }()
+ if err != nil {
+ return "", err
+ } else {
+ prepareScriptContent := strings.Join(getShellLines(scriptFile), "\n")
+ err := exitcode.WriteFileWithCheck(prepareScriptFile, []byte(prepareScriptContent), os.ModePerm)
+ if err != nil {
+ return "", err
+ } else {
+ return prepareScriptFile, nil
+ }
+ }
+}
+
+// getShellLines 根据不同的shell的参数要求,这里可能需要不同的参数或者参数顺序
+func getShellLines(scriptFile string) (newLines []string) {
+ shell := getCurrentShell()
+ switch shell {
+ case "/bin/tcsh":
+ newLines = []string{
+ "#!" + shell,
+ "exec " + shell + " " + scriptFile + " -l",
+ }
+ default:
+ newLines = []string{
+ "#!" + shell,
+ "exec " + shell + " -l " + scriptFile,
+ }
+ }
+ return newLines
+}
+
+func getCurrentShell() (shell string) {
+ if config.GAgentConfig.DetectShell {
+ shell = os.Getenv("SHELL")
+ if strings.TrimSpace(shell) == "" {
+ shell = "/bin/bash"
+ }
+ } else {
+ shell = "/bin/bash"
+ }
+ logs.Info("current shell: ", shell)
+ return
+}
+
+func StartProcessCmd(
+ command string,
+ args []string,
+ workDir string,
+ envMap map[string]string,
+ runUser string,
+ enableExitGroup bool,
+) (*exec.Cmd, error) {
+ cmd := exec.Command(command)
+
+ // arm64机器目前无法通过worker杀进程
+ if enableExitGroup {
+ cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
+ }
+
+ if len(args) > 0 {
+ cmd.Args = append(cmd.Args, args...)
+ }
+
+ if workDir != "" {
+ cmd.Dir = workDir
+ }
+
+ cmd.Env = os.Environ()
+ if envMap != nil {
+ for k, v := range envMap {
+ cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v))
+ }
+ }
+
+ err := ucommand.SetUser(cmd, runUser)
+ if err != nil {
+ logs.Error("set user failed: ", err.Error())
+ return nil, errors.Wrap(err, "Please check [devops.slave.user] in the {agent_dir}/.agent.properties")
+ }
+
+ logs.Info("cmd.Path: ", cmd.Path)
+ logs.Info("cmd.Args: ", cmd.Args)
+ logs.Info("cmd.workDir: ", cmd.Dir)
+ logs.Info("runUser: ", runUser)
+
+ err = cmd.Start()
+ if err != nil {
+ return nil, err
+ }
+
+ return cmd, nil
+}
diff --git a/src/agent/agent/src/pkg/job/do_build_win.go b/src/agent/agent/src/pkg/job/do_build_win.go
new file mode 100644
index 00000000000..3e49070a7ac
--- /dev/null
+++ b/src/agent/agent/src/pkg/job/do_build_win.go
@@ -0,0 +1,193 @@
+//go:build windows
+// +build windows
+
+/*
+ * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.
+ *
+ * A copy of the MIT License is included in this file.
+ *
+ *
+ * Terms of the MIT License:
+ * ---------------------------------------------------
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+ * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package job
+
+import (
+ "fmt"
+ "github.com/pkg/errors"
+ "os"
+ "os/exec"
+ "syscall"
+
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/api"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/config"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/constant"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/i18n"
+ ucommand "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/command"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/process"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/systemutil"
+ "github.com/TencentBlueKing/bk-ci/agentcommon/logs"
+ "github.com/TencentBlueKing/bk-ci/agentcommon/utils/fileutil"
+)
+
+func doBuild(
+ buildInfo *api.ThirdPartyBuildInfo,
+ tmpDir string,
+ workDir string,
+ goEnv map[string]string,
+ runUser string,
+) error {
+ var err error
+ var exitGroup process.ProcessExitGroup
+ enableExitGroup := config.FetchEnvAndCheck(constant.DevopsAgentEnableExitGroup, "true")
+ if enableExitGroup {
+ logs.Info("DEVOPS_AGENT_ENABLE_EXIT_GROUP enable")
+ exitGroup, err = process.NewProcessExitGroup()
+ if err != nil {
+ errMsg := i18n.Localize("StartWorkerProcessFailed", map[string]interface{}{"err": err.Error()})
+ logs.Error(errMsg)
+ workerBuildFinish(buildInfo.ToFinish(false, errMsg, api.BuildProcessStartErrorEnum))
+ return err
+ }
+
+ defer func() {
+ logs.Infof("%s exit group dispose", buildInfo.BuildId)
+ exitGroup.Dispose()
+ }()
+ }
+
+ startCmd := config.GetJava()
+ agentLogPrefix := fmt.Sprintf("%s_%s_agent", buildInfo.BuildId, buildInfo.VmSeqId)
+ errorMsgFile := getWorkerErrorMsgFile(buildInfo.BuildId, buildInfo.VmSeqId)
+ args := []string{
+ "-Djava.io.tmpdir=" + tmpDir,
+ "-Ddevops.agent.error.file=" + errorMsgFile,
+ "-Dbuild.type=AGENT",
+ "-DAGENT_LOG_PREFIX=" + agentLogPrefix,
+ "-Xmx2g", // #5806 兼容性问题,必须独立一行
+ "-jar",
+ config.BuildAgentJarPath(),
+ getEncodedBuildInfo(buildInfo)}
+ cmd, err := StartProcessCmd(startCmd, args, workDir, goEnv, runUser)
+ if err != nil {
+ errMsg := i18n.Localize("StartWorkerProcessFailed", map[string]interface{}{"err": err.Error()})
+ logs.Error(errMsg)
+ workerBuildFinish(buildInfo.ToFinish(false, errMsg, api.BuildProcessStartErrorEnum))
+ return err
+ }
+ pid := cmd.Process.Pid
+
+ if enableExitGroup {
+ logs.Infof("%s process %d add exit group ", buildInfo.BuildId, pid)
+ if err := exitGroup.AddProcess(cmd.Process); err != nil {
+ logs.Errorf("%s add process to %d exit group error %s", buildInfo.BuildId, pid, err.Error())
+ }
+ }
+
+ // 添加需要构建结束后删除的文件
+ buildInfo.ToDelTmpFiles = []string{errorMsgFile}
+
+ GBuildManager.AddBuild(pid, buildInfo)
+ logs.Info(fmt.Sprintf("[%s]|Job#_%s|Build started, pid:%d ", buildInfo.BuildId, buildInfo.VmSeqId, pid))
+
+ // #5806 预先录入异常信息,在构建进程正常结束时清理掉。如果没清理掉,则说明进程非正常退出,可能被OS或人为杀死
+ _ = fileutil.WriteString(errorMsgFile, i18n.Localize("BuilderProcessWasKilled", nil))
+ _ = systemutil.Chmod(errorMsgFile, os.ModePerm)
+
+ err = cmd.Wait()
+ // #5806 从b-xxxx_build_msg.log 读取错误信息,此信息可由worker-agent.jar写入,用于当异常时能够将信息上报给服务器
+ msgFile := getWorkerErrorMsgFile(buildInfo.BuildId, buildInfo.VmSeqId)
+ msg, _ := fileutil.GetString(msgFile)
+ if err != nil {
+ logs.Errorf("build[%s] pid[%d] finish, state=%v err=%v, msg=%s", buildInfo.BuildId, pid, cmd.ProcessState, err, msg)
+ } else {
+ logs.Infof("build[%s] pid[%d] finish, state=%v err=%v, msg=%s", buildInfo.BuildId, pid, cmd.ProcessState, err, msg)
+ }
+
+ // #10362 Worker杀掉当前进程父进程导致Agent误报
+ // agent 改动后可能会导致业务执行完成但是进程被杀掉导致流水线错误,所以将错误只是作为额外信息添加
+ cmdErrMsg := ""
+ if err != nil {
+ cmdErrMsg = "|" + err.Error()
+ }
+
+ success := true
+ if len(msg) == 0 {
+ msg = i18n.Localize("WorkerExit", map[string]interface{}{"pid": pid}) + cmdErrMsg
+ } else {
+ msg += cmdErrMsg
+ success = false
+ }
+
+ GBuildManager.DeleteBuild(pid)
+ if success {
+ workerBuildFinish(buildInfo.ToFinish(success, msg, api.NoErrorEnum))
+ } else {
+ workerBuildFinish(buildInfo.ToFinish(success, msg, api.BuildProcessRunErrorEnum))
+ }
+
+ return nil
+}
+
+func StartProcessCmd(command string, args []string, workDir string, envMap map[string]string, runUser string) (*exec.Cmd, error) {
+ cmd := exec.Command(command)
+
+ if config.FetchEnvAndCheck(constant.DevopsAgentEnableNewConsole, "true") {
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ CreationFlags: constant.WinCommandNewConsole,
+ NoInheritHandles: true,
+ }
+ logs.Info("DEVOPS_AGENT_ENABLE_NEW_CONSOLE enabled")
+ }
+
+ if len(args) > 0 {
+ cmd.Args = append(cmd.Args, args...)
+ }
+
+ if workDir != "" {
+ cmd.Dir = workDir
+ }
+
+ cmd.Env = os.Environ()
+ if envMap != nil {
+ for k, v := range envMap {
+ cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", k, v))
+ }
+ }
+
+ err := ucommand.SetUser(cmd, runUser)
+ if err != nil {
+ logs.Error("set user failed: ", err.Error())
+ return nil, errors.Wrap(err, "Please check [devops.slave.user] in the {agent_dir}/.agent.properties")
+ }
+
+ logs.Info("cmd.Path: ", cmd.Path)
+ logs.Info("cmd.Args: ", cmd.Args)
+ logs.Info("cmd.workDir: ", cmd.Dir)
+ logs.Info("runUser: ", runUser)
+
+ err = cmd.Start()
+ if err != nil {
+ return nil, err
+ }
+
+ return cmd, nil
+}
diff --git a/src/agent/agent/src/pkg/job/job.go b/src/agent/agent/src/pkg/job/job.go
deleted file mode 100644
index 00ba6971cb4..00000000000
--- a/src/agent/agent/src/pkg/job/job.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package job
-
-import (
- "fmt"
-
- "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/systemutil"
-)
-
-const (
- errorMsgFileSuffix = "build_msg.log"
- prepareStartScriptFilePrefix = "devops_agent_prepare_start"
- prepareStartScriptFileSuffix = ".sh"
- startScriptFilePrefix = "devops_agent_start"
- startScriptFileSuffix = ".sh"
-)
-
-// getWorkerErrorMsgFile 获取worker执行错误信息的日志文件
-func getWorkerErrorMsgFile(buildId, vmSeqId string) string {
- return fmt.Sprintf("%s/build_tmp/%s_%s_%s",
- systemutil.GetWorkDir(), buildId, vmSeqId, errorMsgFileSuffix)
-}
-
-// getUnixWorkerPrepareStartScriptFile 获取unix系统,主要是darwin和linux的prepare start script文件
-func getUnixWorkerPrepareStartScriptFile(projectId, buildId, vmSeqId string) string {
- return fmt.Sprintf("%s/%s_%s_%s_%s%s",
- systemutil.GetWorkDir(), prepareStartScriptFilePrefix, projectId, buildId, vmSeqId, prepareStartScriptFileSuffix)
-}
-
-// getUnixWorkerStartScriptFile 获取unix系统,主要是darwin和linux的prepare start script文件
-func getUnixWorkerStartScriptFile(projectId, buildId, vmSeqId string) string {
- return fmt.Sprintf("%s/%s_%s_%s_%s%s",
- systemutil.GetWorkDir(), startScriptFilePrefix, projectId, buildId, vmSeqId, startScriptFileSuffix)
-}
-
-// 校验当前是否有正在跑的任务
-func CheckRunningJob() bool {
- if GBuildManager.GetPreInstancesCount() > 0 ||
- GBuildManager.GetInstanceCount() > 0 ||
- GBuildDockerManager.GetInstanceCount() > 0 {
- return true
- }
- return false
-}
diff --git a/src/agent/agent/src/pkg/job_docker/job_docker.go b/src/agent/agent/src/pkg/job_docker/job_docker.go
index 51de755e01a..6448fdff416 100644
--- a/src/agent/agent/src/pkg/job_docker/job_docker.go
+++ b/src/agent/agent/src/pkg/job_docker/job_docker.go
@@ -5,11 +5,11 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
+ "github.com/docker/docker/api/types/registry"
"os"
"strings"
"github.com/TencentBlueKing/bk-ci/agent/src/pkg/api"
- "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/docker/docker/client"
@@ -20,7 +20,7 @@ import (
const (
LocalDockerBuildTmpDirName = "docker_build_tmp"
LocalDockerWorkSpaceDirName = "docker_workspace"
- DockerLogDir = "/data/logs"
+ DockerLogDir = "/data/devops/logs"
)
type DockerHostInfo struct {
@@ -29,7 +29,7 @@ type DockerHostInfo struct {
type ImagePullInfo struct {
ImageName string
- AuthType types.AuthConfig
+ AuthType registry.AuthConfig
}
type ContainerCreateInfo struct {
@@ -40,7 +40,7 @@ type ContainerCreateInfo struct {
}
func parseApiDockerOptions(o api.DockerOptions) []string {
- args := []string{}
+ var args []string
if o.Volumes != nil && len(o.Volumes) > 0 {
for _, v := range o.Volumes {
args = append(args, "--volume", strings.TrimSpace(v))
@@ -57,10 +57,14 @@ func parseApiDockerOptions(o api.DockerOptions) []string {
args = append(args, "--gpus", strings.TrimSpace(o.Gpus))
}
+ if o.Privileged != false {
+ args = append(args, "--privileged")
+ }
+
return args
}
-func ParseDockeroptions(dockerClient *client.Client, userOptions api.DockerOptions) (*ContainerConfig, error) {
+func ParseDockerOptions(dockerClient *client.Client, userOptions api.DockerOptions) (*ContainerConfig, error) {
// 将指定好的options直接换成args
argv := parseApiDockerOptions(userOptions)
if len(argv) == 0 {
@@ -68,9 +72,9 @@ func ParseDockeroptions(dockerClient *client.Client, userOptions api.DockerOptio
}
// 解析args为flagSet
- flagset := pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError)
- copts := addFlags(flagset)
- err := flagset.Parse(argv)
+ flagSet := pflag.NewFlagSet(os.Args[0], pflag.ContinueOnError)
+ copts := addFlags(flagSet)
+ err := flagSet.Parse(argv)
if err != nil {
errMsg := fmt.Sprintf("解析用户docker options失败: %s", err.Error())
return nil, errors.New(errMsg)
@@ -84,7 +88,7 @@ func ParseDockeroptions(dockerClient *client.Client, userOptions api.DockerOptio
}
// 解析配置为可用docker配置, 目前只有linux支持,所以只使用linux相关配置
- containerConfig, err := parse(flagset, copts, ping.OSType)
+ containerConfig, err := parse(flagSet, copts, ping.OSType)
if err != nil {
errMsg := fmt.Sprintf("解析用户docker options 为docker配置 错误: %s", err.Error())
return nil, errors.New(errMsg)
@@ -93,9 +97,9 @@ func ParseDockeroptions(dockerClient *client.Client, userOptions api.DockerOptio
return containerConfig, nil
}
-// policy 为空,并且容器镜像的标签是 :latest, image-pull-policy 会自动设置为 always
+// IfPullImage policy 为空,并且容器镜像的标签是 :latest, image-pull-policy 会自动设置为 always
// policy 为空,并且为容器镜像指定了非 :latest 的标签, image-pull-policy 就会自动设置为 if-not-present
-func IfPullImage(localExist, islatest bool, policy string) bool {
+func IfPullImage(localExist, isLatest bool, policy string) bool {
// 为空和枚举写错走一套逻辑
switch policy {
case api.ImagePullPolicyAlways.String():
@@ -107,7 +111,7 @@ func IfPullImage(localExist, islatest bool, policy string) bool {
return false
}
default:
- if islatest {
+ if isLatest {
return true
} else {
if !localExist {
@@ -125,7 +129,7 @@ func GenerateDockerAuth(user, pass string) (string, error) {
return "", nil
}
- authConfig := types.AuthConfig{
+ authConfig := registry.AuthConfig{
Username: user,
Password: pass,
}
diff --git a/src/agent/agent/src/pkg/job_docker/opts.go b/src/agent/agent/src/pkg/job_docker/opts.go
index f4f390451c6..a14e38f935b 100644
--- a/src/agent/agent/src/pkg/job_docker/opts.go
+++ b/src/agent/agent/src/pkg/job_docker/opts.go
@@ -324,7 +324,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*Con
// Validate the input mac address
if copts.macAddress != "" {
if _, err := opts.ValidateMACAddress(copts.macAddress); err != nil {
- return nil, errors.Errorf("%s is not a valid mac address", copts.macAddress)
+ return nil, fmt.Errorf("%s is not a valid mac address", copts.macAddress)
}
}
if copts.stdin {
@@ -340,7 +340,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*Con
swappiness := copts.swappiness
if swappiness != -1 && (swappiness < 0 || swappiness > 100) {
- return nil, errors.Errorf("invalid value: %d. Valid memory swappiness range is 0-100", swappiness)
+ return nil, fmt.Errorf("invalid value: %d. Valid memory swappiness range is 0-100", swappiness)
}
mounts := copts.mounts.Value()
@@ -419,7 +419,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*Con
// Merge in exposed ports to the map of published ports
for _, e := range copts.expose.GetAll() {
if strings.Contains(e, ":") {
- return nil, errors.Errorf("invalid port format for --expose: %s", e)
+ return nil, fmt.Errorf("invalid port format for --expose: %s", e)
}
// support two formats for expose, original format /[]
// or /[]
@@ -428,7 +428,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*Con
// if expose a port, the start and end port are the same
start, end, err := nat.ParsePortRange(port)
if err != nil {
- return nil, errors.Errorf("invalid range format for --expose: %s, error: %s", e, err)
+ return nil, fmt.Errorf("invalid range format for --expose: %s, error: %s", e, err)
}
for i := start; i <= end; i++ {
p, err := nat.NewPort(proto, strconv.FormatUint(i, 10))
@@ -477,22 +477,22 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*Con
pidMode := container.PidMode(copts.pidMode)
if !pidMode.Valid() {
- return nil, errors.Errorf("--pid: invalid PID mode")
+ return nil, errors.New("--pid: invalid PID mode")
}
utsMode := container.UTSMode(copts.utsMode)
if !utsMode.Valid() {
- return nil, errors.Errorf("--uts: invalid UTS mode")
+ return nil, errors.New("--uts: invalid UTS mode")
}
usernsMode := container.UsernsMode(copts.usernsMode)
if !usernsMode.Valid() {
- return nil, errors.Errorf("--userns: invalid USER mode")
+ return nil, errors.New("--userns: invalid USER mode")
}
cgroupnsMode := container.CgroupnsMode(copts.cgroupnsMode)
if !cgroupnsMode.Valid() {
- return nil, errors.Errorf("--cgroupns: invalid CGROUP mode")
+ return nil, errors.New("--cgroupns: invalid CGROUP mode")
}
restartPolicy, err := opts.ParseRestartPolicy(copts.restartPolicy)
@@ -526,7 +526,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*Con
copts.healthRetries != 0
if copts.noHealthcheck {
if haveHealthSettings {
- return nil, errors.Errorf("--no-healthcheck conflicts with --health-* options")
+ return nil, errors.New("--no-healthcheck conflicts with --health-* options")
}
healthConfig = &container.HealthConfig{Test: strslice.StrSlice{"NONE"}}
} else if haveHealthSettings {
@@ -535,16 +535,16 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*Con
probe = []string{"CMD-SHELL", copts.healthCmd}
}
if copts.healthInterval < 0 {
- return nil, errors.Errorf("--health-interval cannot be negative")
+ return nil, errors.New("--health-interval cannot be negative")
}
if copts.healthTimeout < 0 {
- return nil, errors.Errorf("--health-timeout cannot be negative")
+ return nil, errors.New("--health-timeout cannot be negative")
}
if copts.healthRetries < 0 {
- return nil, errors.Errorf("--health-retries cannot be negative")
+ return nil, errors.New("--health-retries cannot be negative")
}
if copts.healthStartPeriod < 0 {
- return nil, fmt.Errorf("--health-start-period cannot be negative")
+ return nil, errors.New("--health-start-period cannot be negative")
}
healthConfig = &container.HealthConfig{
@@ -660,7 +660,7 @@ func parse(flags *pflag.FlagSet, copts *containerOptions, serverOS string) (*Con
}
if copts.autoRemove && !hostConfig.RestartPolicy.IsNone() {
- return nil, errors.Errorf("Conflicting options: --restart and --rm")
+ return nil, errors.New("Conflicting options: --restart and --rm")
}
// only set this value if the user provided the flag, else it should default to nil
@@ -717,7 +717,7 @@ func parseNetworkOpts(copts *containerOptions) (map[string]*networktypes.Endpoin
return nil, err
}
if _, ok := endpoints[n.Target]; ok {
- return nil, errdefs.InvalidParameter(errors.Errorf("network %q is specified multiple times", n.Target))
+ return nil, errdefs.InvalidParameter(fmt.Errorf("network %q is specified multiple times", n.Target))
}
// For backward compatibility: if no custom options are provided for the network,
@@ -814,7 +814,7 @@ func convertToStandardNotation(ports []string) ([]string, error) {
for _, param := range strings.Split(publish, ",") {
k, v, ok := strings.Cut(param, "=")
if !ok || k == "" {
- return optsList, errors.Errorf("invalid publish opts format (should be name=value but got '%s')", param)
+ return optsList, fmt.Errorf("invalid publish opts format (should be name=value but got '%s')", param)
}
params[k] = v
}
@@ -829,7 +829,7 @@ func convertToStandardNotation(ports []string) ([]string, error) {
func parseLoggingOpts(loggingDriver string, loggingOpts []string) (map[string]string, error) {
loggingOptsMap := opts.ConvertKVStringsToMap(loggingOpts)
if loggingDriver == "none" && len(loggingOpts) > 0 {
- return map[string]string{}, errors.Errorf("invalid logging opts for driver %s", loggingDriver)
+ return map[string]string{}, fmt.Errorf("invalid logging opts for driver %s", loggingDriver)
}
return loggingOptsMap, nil
}
@@ -843,16 +843,16 @@ func parseSecurityOpts(securityOpts []string) ([]string, error) {
}
if (!ok || v == "") && k != "no-new-privileges" {
// "no-new-privileges" is the only option that does not require a value.
- return securityOpts, errors.Errorf("Invalid --security-opt: %q", opt)
+ return securityOpts, fmt.Errorf("Invalid --security-opt: %q", opt)
}
if k == "seccomp" && v != "unconfined" {
f, err := os.ReadFile(v)
if err != nil {
- return securityOpts, errors.Errorf("opening seccomp profile (%s) failed: %v", v, err)
+ return securityOpts, errors.Wrapf(err, "opening seccomp profile (%s) failed", v)
}
b := bytes.NewBuffer(nil)
if err := json.Compact(b, f); err != nil {
- return securityOpts, errors.Errorf("compacting json for seccomp profile (%s) failed: %v", v, err)
+ return securityOpts, errors.Wrapf(err, "compacting json for seccomp profile (%s) failed", v)
}
securityOpts[key] = fmt.Sprintf("seccomp=%s", b.Bytes())
}
@@ -886,7 +886,7 @@ func parseStorageOpts(storageOpts []string) (map[string]string, error) {
for _, option := range storageOpts {
k, v, ok := strings.Cut(option, "=")
if !ok {
- return nil, errors.Errorf("invalid storage option")
+ return nil, errors.New("invalid storage option")
}
m[k] = v
}
@@ -901,7 +901,7 @@ func parseDevice(device, serverOS string) (container.DeviceMapping, error) {
case "windows":
return parseWindowsDevice(device)
}
- return container.DeviceMapping{}, errors.Errorf("unknown server OS: %s", serverOS)
+ return container.DeviceMapping{}, fmt.Errorf("unknown server OS: %s", serverOS)
}
// parseLinuxDevice parses a device mapping string to a container.DeviceMapping struct
@@ -925,7 +925,7 @@ func parseLinuxDevice(device string) (container.DeviceMapping, error) {
case 1:
src = arr[0]
default:
- return container.DeviceMapping{}, errors.Errorf("invalid device specification: %s", device)
+ return container.DeviceMapping{}, fmt.Errorf("invalid device specification: %s", device)
}
if dst == "" {
@@ -955,7 +955,7 @@ func validateDeviceCgroupRule(val string) (string, error) {
return val, nil
}
- return val, errors.Errorf("invalid device cgroup format '%s'", val)
+ return val, fmt.Errorf("invalid device cgroup format '%s'", val)
}
// validDeviceMode checks if the mode for device is valid or not.
@@ -987,7 +987,7 @@ func validateDevice(val string, serverOS string) (string, error) {
// Windows does validation entirely server-side
return val, nil
}
- return "", errors.Errorf("unknown server OS: %s", serverOS)
+ return "", fmt.Errorf("unknown server OS: %s", serverOS)
}
// validateLinuxPath is the implementation of validateDevice knowing that the
@@ -1002,12 +1002,12 @@ func validateLinuxPath(val string, validator func(string) bool) (string, error)
var mode string
if strings.Count(val, ":") > 2 {
- return val, errors.Errorf("bad format for path: %s", val)
+ return val, fmt.Errorf("bad format for path: %s", val)
}
split := strings.SplitN(val, ":", 3)
if split[0] == "" {
- return val, errors.Errorf("bad format for path: %s", val)
+ return val, fmt.Errorf("bad format for path: %s", val)
}
switch len(split) {
case 1:
@@ -1026,13 +1026,13 @@ func validateLinuxPath(val string, validator func(string) bool) (string, error)
containerPath = split[1]
mode = split[2]
if isValid := validator(split[2]); !isValid {
- return val, errors.Errorf("bad mode specified: %s", mode)
+ return val, fmt.Errorf("bad mode specified: %s", mode)
}
val = fmt.Sprintf("%s:%s:%s", split[0], containerPath, mode)
}
if !path.IsAbs(containerPath) {
- return val, errors.Errorf("%s is not an absolute path", containerPath)
+ return val, fmt.Errorf("%s is not an absolute path", containerPath)
}
return val, nil
}
@@ -1045,5 +1045,5 @@ func validateAttach(val string) (string, error) {
return s, nil
}
}
- return val, errors.Errorf("valid streams are STDIN, STDOUT and STDERR")
+ return val, errors.New("valid streams are STDIN, STDOUT and STDERR")
}
diff --git a/src/agent/agent/src/pkg/job_docker/opts_test.go b/src/agent/agent/src/pkg/job_docker/opts_test.go
index 97e243d95be..a8e14294fbc 100644
--- a/src/agent/agent/src/pkg/job_docker/opts_test.go
+++ b/src/agent/agent/src/pkg/job_docker/opts_test.go
@@ -2,6 +2,7 @@ package job_docker
import (
"fmt"
+ "github.com/pkg/errors"
"io"
"os"
"runtime"
@@ -12,7 +13,6 @@ import (
"github.com/docker/docker/api/types/container"
networktypes "github.com/docker/docker/api/types/network"
"github.com/docker/go-connections/nat"
- "github.com/pkg/errors"
"github.com/spf13/pflag"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
@@ -283,7 +283,7 @@ func compareRandomizedStrings(a, b, c, d string) error {
if a == d && b == c {
return nil
}
- return errors.Errorf("strings don't match")
+ return errors.New("strings don't match")
}
// Simple parse with MacAddress validation
diff --git a/src/agent/agent/src/pkg/pipeline/pipeline.go b/src/agent/agent/src/pkg/pipeline/pipeline.go
index edaed3a3340..94118e99849 100644
--- a/src/agent/agent/src/pkg/pipeline/pipeline.go
+++ b/src/agent/agent/src/pkg/pipeline/pipeline.go
@@ -155,7 +155,7 @@ func runCommandPipelineWindows(pipeline *CommandPipeline, lines []string) error
output, err := command.RunCommand(scriptFile, []string{} /*args*/, systemutil.GetWorkDir(), nil)
if err != nil {
_, _ = api.UpdatePipelineStatus(api.NewPipelineResponse(pipeline.SeqId, StatusFailure, "run pipeline failed: "+err.Error()+"\noutput: "+string(output)))
- return errors.Wrap(err, "run pipeline failed")
+ return errors.Wrapf(err, "run pipeline failed")
}
_, _ = api.UpdatePipelineStatus(api.NewPipelineResponse(pipeline.SeqId, StatusSuccess, string(output)))
diff --git a/src/agent/agent/src/pkg/upgrade/operation.go b/src/agent/agent/src/pkg/upgrade/operation.go
index ba079d3e98d..27e08a2ffd6 100644
--- a/src/agent/agent/src/pkg/upgrade/operation.go
+++ b/src/agent/agent/src/pkg/upgrade/operation.go
@@ -55,7 +55,7 @@ func UninstallAgent() {
// 错误了也不退出,最少也要干掉daemon
}
logs.Warn("agent process exiting")
- systemutil.ExitProcess(constant.DAEMON_EXIT_CODE)
+ systemutil.ExitProcess(constant.DaemonExitCode)
}
// runUninstallUpgrader 卸载的区分开,方便进行退出处理
@@ -67,7 +67,7 @@ func runUninstallUpgrader(action string) error {
if !systemutil.IsWindows() {
err := systemutil.Chmod(scripPath, 0777)
if err != nil {
- logs.Error("agentUpgrade|chmod failed: ", err.Error())
+ logs.WithError(err).Error("agentUpgrade|chmod failed")
return errors.New("chmod failed: ")
}
}
@@ -76,13 +76,13 @@ func runUninstallUpgrader(action string) error {
pid, err := command.StartProcess(scripPath, args, systemutil.GetWorkDir(), nil, "")
if err != nil {
- logs.Error("agentUpgrade|run uninstall upgrader failed: ", err.Error())
+ logs.WithError(err).Error("agentUpgrade|run uninstall upgrader failed")
return errors.New("run uninstall upgrader failed")
}
logs.Info("agentUpgrade|start uninstall process success, pid: ", pid)
logs.Warn("agentUpgrade|agent uninstall process exiting")
- systemutil.ExitProcess(constant.DAEMON_EXIT_CODE)
+ systemutil.ExitProcess(constant.DaemonExitCode)
return nil
}
@@ -95,7 +95,7 @@ func runUpgrader(action string) error {
if !systemutil.IsWindows() {
err := systemutil.Chmod(scripPath, 0777)
if err != nil {
- logs.Error("agentUpgrade|chmod failed: ", err.Error())
+ logs.WithError(err).Error("agentUpgrade|chmod failed")
return errors.New("chmod failed: ")
}
}
@@ -107,7 +107,7 @@ func runUpgrader(action string) error {
pid, err := command.StartProcess(scripPath, args, systemutil.GetWorkDir(), nil, "")
if err != nil {
- logs.Error("agentUpgrade|run upgrader failed: ", err.Error())
+ logs.WithError(err).Error("agentUpgrade|run upgrader failed")
return errors.New("run upgrader failed")
}
logs.Info("agentUpgrade|start process success, pid: ", pid)
@@ -141,7 +141,7 @@ func DoUpgradeOperation(changeItems upgradeChangeItem) error {
systemutil.GetWorkDir()+"/"+config.WorkAgentFile,
true)
if err != nil {
- logs.Error("agentUpgrade|replace work agent file failed: ", err.Error())
+ logs.WithError(err).Error("agentUpgrade|replace work agent file failed")
return errors.New("replace work agent file failed")
}
logs.Info("agentUpgrade|replace agent file done")
@@ -168,12 +168,12 @@ func DoUpgradeOperation(changeItems upgradeChangeItem) error {
config.GetDockerInitFilePath(),
true)
if err != nil {
- logs.Error("agentUpgrade|replace work docker init file failed: ", err.Error())
+ logs.WithError(err).Error("agentUpgrade|replace work docker init file failed")
return errors.New("replace work docker init file failed")
}
// 授予文件可执行权限,每次升级后赋予权限可以减少直接在启动时赋予的并发赋予的情况
if err = systemutil.Chmod(config.GetDockerInitFilePath(), os.ModePerm); err != nil {
- logs.Error("agentUpgrade|chmod work docker init file failed: ", err.Error())
+ logs.WithError(err).Error("agentUpgrade|chmod work docker init file failed")
return errors.New("chmod work docker init file failed")
}
@@ -210,7 +210,7 @@ func DoUpgradeJdk() error {
go func() {
files, err := os.ReadDir(workDir)
if err != nil {
- logs.Error("agentUpgrade|upgrade jdk remove old jdk file error", err)
+ logs.WithError(err).Error("agentUpgrade|upgrade jdk remove old jdk file error")
return
}
for _, file := range files {
@@ -218,7 +218,7 @@ func DoUpgradeJdk() error {
file.Name() != jdkTmpName {
err = os.RemoveAll(workDir + "/" + file.Name())
if err != nil {
- logs.Error("agentUpgrade|upgrade jdk remove old jdk file error", err)
+ logs.WithError(err).Error("agentUpgrade|upgrade jdk remove old jdk file error")
}
}
}
diff --git a/src/agent/agent/src/pkg/upgrade/upgrade.go b/src/agent/agent/src/pkg/upgrade/upgrade.go
index 847d5114bea..72b9daa5482 100644
--- a/src/agent/agent/src/pkg/upgrade/upgrade.go
+++ b/src/agent/agent/src/pkg/upgrade/upgrade.go
@@ -28,6 +28,7 @@
package upgrade
import (
+ "github.com/pkg/errors"
"os"
"strings"
"sync/atomic"
@@ -38,8 +39,6 @@ import (
"github.com/TencentBlueKing/bk-ci/agent/src/pkg/upgrade/download"
"github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/command"
- "github.com/pkg/errors"
-
"github.com/TencentBlueKing/bk-ci/agentcommon/logs"
"github.com/TencentBlueKing/bk-ci/agent/src/pkg/api"
@@ -50,7 +49,7 @@ import (
var JdkVersion = &JdkVersionType{}
-// JdkVersion jdk版本信息缓存
+// JdkVersionType jdk版本信息缓存
type JdkVersionType struct {
JdkFileModTime time.Time
// 版本信息,原子级的 []string
@@ -149,7 +148,7 @@ func AgentUpgrade(upgradeItem *api.UpgradeItem, hasBuild bool) {
logs.Info("agentUpgrade|download upgrade files done")
err := DoUpgradeOperation(changeItems)
if err != nil {
- logs.Error("agentUpgrade|do upgrade operation failed", err)
+ logs.WithError(err).Error("agentUpgrade|do upgrade operation failed")
} else {
success = true
}
@@ -161,7 +160,7 @@ func SyncJdkVersion() error {
stat, err := os.Stat(config.GAgentConfig.JdkDirPath)
if err != nil {
if os.IsNotExist(err) {
- logs.Error("syncJdkVersion no jdk dir find", err)
+ logs.WithError(err).Error("syncJdkVersion no jdk dir find")
// jdk版本置为空,否则会一直保持有版本的状态
JdkVersion.SetVersion([]string{})
return nil
@@ -175,7 +174,7 @@ func SyncJdkVersion() error {
version, err := getJdkVersion()
if err != nil {
// 拿取错误时直接下载新的
- logs.Error("syncJdkVersion getJdkVersion err", err)
+ logs.WithError(err).Error("syncJdkVersion getJdkVersion err")
return nil
}
JdkVersion.SetVersion(version)
@@ -191,7 +190,7 @@ func SyncJdkVersion() error {
version, err := getJdkVersion()
if err != nil {
// 拿取错误时直接下载新的
- logs.Error("syncJdkVersion getJdkVersion err", err)
+ logs.WithError(err).Error("syncJdkVersion getJdkVersion err")
JdkVersion.SetVersion([]string{})
return nil
}
@@ -247,7 +246,7 @@ func SyncDockerInitFileMd5() error {
func getJdkVersion() ([]string, error) {
jdkVersion, err := command.RunCommand(config.GetJava(), []string{"-version"}, "", nil)
if err != nil {
- logs.Error("agent get jdk version failed: ", err.Error())
+ logs.WithError(err).Error("agent get jdk version failed")
exitcode.CheckSignalJdkError(err)
return nil, errors.Wrap(err, "agent get jdk version failed")
}
@@ -346,7 +345,7 @@ func downloadUpgradeAgent(workDir, upgradeDir string) (agentChanged bool) {
logs.Info("agentUpgrade|download upgrader start")
_, err := download.DownloadUpgradeFile(upgradeDir)
if err != nil {
- logs.Error("agentUpgrade|download upgrader failed", err)
+ logs.WithError(err).Error("agentUpgrade|download upgrader failed")
return false
}
logs.Info("agentUpgrade|download upgrader done")
@@ -354,7 +353,7 @@ func downloadUpgradeAgent(workDir, upgradeDir string) (agentChanged bool) {
logs.Info("agentUpgrade|download daemon start")
newDaemonMd5, err := download.DownloadDaemonFile(upgradeDir)
if err != nil {
- logs.Error("agentUpgrade|download daemon failed", err)
+ logs.WithError(err).Error("agentUpgrade|download daemon failed")
return false
}
logs.Info("agentUpgrade|download daemon done")
diff --git a/src/agent/agent/src/pkg/upgrader/upgrader.go b/src/agent/agent/src/pkg/upgrader/upgrader.go
index 2b5b9402d52..2a0d8e20000 100644
--- a/src/agent/agent/src/pkg/upgrader/upgrader.go
+++ b/src/agent/agent/src/pkg/upgrader/upgrader.go
@@ -1,3 +1,5 @@
+//go:build linux || darwin
+
/*
* Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
*
@@ -28,8 +30,10 @@
package upgrader
import (
- "errors"
"fmt"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/constant"
+ innerFileUtil "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/fileutil"
+ "github.com/pkg/errors"
"os"
"strconv"
"time"
@@ -56,7 +60,7 @@ func DoUpgradeAgent() error {
totalLock := flock.New(fmt.Sprintf("%s/%s.lock", systemutil.GetRuntimeDir(), systemutil.TotalLock))
err := totalLock.Lock()
if err = totalLock.Lock(); err != nil {
- logs.Error("get total lock failed, exit", err.Error())
+ logs.WithError(err).Error("get total lock failed, exit")
return errors.New("get total lock failed")
}
defer func() { totalLock.Unlock() }()
@@ -66,10 +70,6 @@ func DoUpgradeAgent() error {
#4686
1、kill devopsDaemon进程的行为在 macos 下, 如果当前是由 launchd 启动的(比如mac重启之后,devopsDaemon会由launchd接管启动)
当upgrader进程触发kill devopsDaemon时,会导致当前upgrader进程也被系统一并停掉,所以要排除macos的进程停止操作,否则会导致升级中断
-
- 2、windows 因早期daemon缺失 pid文件,在安装多个agent的机器上无法很正确的寻找到正确的进程,并且windows的启动方式较多,早期用户会使用
- 直接双击devopsDaemon.exe文件来启动,以此来保证构建进程能够正确拉起带UI的程序,所以这块无法正确查找到进程,因此暂时也不考虑windows的
- devopsDaemon.exe文件升级。 windows需要手动升级
*/
if daemonChange && systemutil.IsLinux() {
tryKillAgentProcess(daemonProcess) // macos 在升级后只能使用手动重启
@@ -91,18 +91,18 @@ func DoUpgradeAgent() error {
if agentChange {
err = replaceAgentFile(config.GetClienAgentFile())
if err != nil {
- logs.Error("replace agent file failed: ", err.Error())
+ logs.WithError(err).Error("replace agent file failed")
}
}
if daemonChange {
- err = replaceAgentFile(config.GetClientDaemonFile()) // #4686 如果windows下daemon进程仍然存在,则会替换失败
+ err = replaceAgentFile(config.GetClientDaemonFile())
if err != nil {
- logs.Error("replace daemon file failed: ", err.Error())
+ logs.WithError(err).Error("replace daemon file failed")
}
if systemutil.IsLinux() { // #4686 如上,上面仅停止Linux的devopsDaemon进程,则也只重启动Linux的
if startErr := StartDaemon(); startErr != nil {
- logs.Error("start daemon failed: ", startErr.Error())
+ logs.WithError(startErr).Error("start daemon failed")
return startErr
}
logs.Info("agent start done")
@@ -142,7 +142,7 @@ func tryKillAgentProcess(processName string) {
func DoUninstallAgent() error {
err := UninstallAgent()
if err != nil {
- logs.Error("uninstall agent failed: ", err.Error())
+ logs.WithError(err).Error("uninstall agent failed")
return errors.New("uninstall agent failed")
}
return nil
@@ -186,7 +186,7 @@ func StartDaemon() error {
startCmd := workDir + "/" + config.GetClientDaemonFile()
if err := fileutil.SetExecutable(startCmd); err != nil {
- logs.Warn(fmt.Errorf("chmod daemon file failed: %v", err))
+ logs.WithError(err).Warn("chmod daemon file failed")
return err
}
@@ -199,32 +199,26 @@ func StartDaemon() error {
return nil
}
-func StopAgent() error {
- logs.Info("start stop agent")
-
- workDir := systemutil.GetWorkDir()
- startCmd := workDir + "/" + config.GetStopScript()
- output, err := command.RunCommand(startCmd, []string{} /*args*/, workDir, nil)
- if err != nil {
- logs.Error("run stop script failed: ", err.Error())
- logs.Error("output: ", string(output))
- return errors.New("run stop script failed")
- }
- logs.Info("output: ", string(output))
- return nil
-}
-
func replaceAgentFile(fileName string) error {
logs.Info("replace agent file: ", fileName)
src := systemutil.GetUpgradeDir() + "/" + fileName
dst := systemutil.GetWorkDir() + "/" + fileName
- if _, err := fileutil.CopyFile(src, dst, true); err != nil {
- logs.Warn(fmt.Sprintf("copy file %s to %s failed: %s", src, dst, err))
- return err
+
+ // 查询 dst 的状态,如果没有的话使用预设权限\
+ perm := constant.CommonFileModePerm
+ if stat, err := os.Stat(dst); err != nil {
+ logs.WithError(err).Warnf("replaceAgentFile %s stat error", dst)
+ } else if stat != nil {
+ perm = stat.Mode()
}
- if err := fileutil.SetExecutable(dst); err != nil {
- logs.Warn(fmt.Sprintf("chmod %s file failed: %s", dst, err))
- return err
+
+ srcFile, err := os.Open(src)
+ if err != nil {
+ return errors.Wrapf(err, "replaceAgentFile open %s error", src)
+ }
+
+ if err := innerFileUtil.AtomicWriteFile(dst, srcFile, perm); err != nil {
+ return errors.Wrapf(err, "replaceAgentFile AtomicWriteFile %s error", dst)
}
return nil
}
diff --git a/src/agent/agent/src/pkg/upgrader/upgrader_win.go b/src/agent/agent/src/pkg/upgrader/upgrader_win.go
new file mode 100644
index 00000000000..f39ac1201ba
--- /dev/null
+++ b/src/agent/agent/src/pkg/upgrader/upgrader_win.go
@@ -0,0 +1,328 @@
+//go:build windows
+
+/*
+ * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.
+ *
+ * A copy of the MIT License is included in this file.
+ *
+ *
+ * Terms of the MIT License:
+ * ---------------------------------------------------
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+ * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package upgrader
+
+import (
+ "fmt"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/constant"
+ innerFileUtil "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/fileutil"
+ "github.com/pkg/errors"
+ "golang.org/x/sys/windows/svc/mgr"
+ "os"
+ "os/exec"
+ "strconv"
+ "strings"
+ "syscall"
+ "time"
+
+ "github.com/TencentBlueKing/bk-ci/agentcommon/logs"
+
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/config"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/command"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/systemutil"
+ "github.com/TencentBlueKing/bk-ci/agentcommon/utils/fileutil"
+
+ "github.com/gofrs/flock"
+
+ "github.com/capnspacehook/taskmaster"
+ "github.com/shirou/gopsutil/v4/process"
+)
+
+type startType string
+
+const (
+ agentProcess = "agent"
+ daemonProcess = "daemon"
+
+ // 服务,执行计划,手动
+ serviceStart startType = "service"
+ taskStart startType = "task"
+ manualStart startType = "manual"
+)
+
+// DoUpgradeAgent 升级agent
+// 1、通过service启动的daemon因为go本身内部注册了daemon导致权限模型有些未知问题,无法更新daemon后启动,只能更新agent
+// 2、通过执行计划启动的daemon因为具有登录态,可以直接执行脚本拉起
+// 3、用户双击启动的daemon和service一样,无法更新daemon,只能更新agent
+func DoUpgradeAgent() error {
+ logs.Info("start upgrade agent")
+ config.Init(false)
+
+ totalLock := flock.New(fmt.Sprintf("%s/%s.lock", systemutil.GetRuntimeDir(), systemutil.TotalLock))
+ err := totalLock.Lock()
+ if err = totalLock.Lock(); err != nil {
+ logs.WithError(err).Error("get total lock failed, exit")
+ return errors.New("get total lock failed")
+ }
+ defer func() { totalLock.Unlock() }()
+
+ startT := manualStart
+ var winTask *taskmaster.RegisteredTask = nil
+ // 先查询服务
+ serviceName := "devops_agent_" + config.GAgentConfig.AgentId
+ ok := findService(serviceName)
+ if ok {
+ startT = serviceStart
+ } else {
+ if task, taskOk := findTask(serviceName); taskOk {
+ winTask = task
+ startT = taskStart
+ }
+ }
+ // 理论上不可能,但是作为补充可以为后文提供逻辑依据
+ if startT == taskStart && winTask == nil {
+ logs.Warn("win task not exist update agent")
+ startT = manualStart
+ }
+
+ logs.Infof("agent process start by %s", startT)
+
+ daemonChange := false
+ if startT == taskStart {
+ daemonChange, err = checkUpgradeFileChange(config.GetClientDaemonFile())
+ if err != nil {
+ logs.WithError(err).Warn("check daemon upgrade file change failed")
+ }
+ }
+ daemonPid := 0
+ if daemonChange {
+ daemonPid, err = tryKillAgentProcess(daemonProcess)
+ if err != nil {
+ logs.WithError(err).Error(fmt.Sprintf("try kill daemon process failed"))
+ }
+ }
+
+ agentChange, err := checkUpgradeFileChange(config.GetClienAgentFile())
+ if err != nil {
+ logs.WithError(err).Warn("check agent upgrade file change failed")
+ }
+ agentPid := 0
+ if agentChange {
+ agentPid, err = tryKillAgentProcess(agentProcess)
+ if err != nil {
+ logs.WithError(err).Error(fmt.Sprintf("try kill agent process failed"))
+ }
+ }
+
+ if !agentChange && !daemonChange {
+ logs.Info("upgrade nothing, exit")
+ return nil
+ }
+
+ // 检查进程是否被杀掉
+ daemonExist := true
+ agentExist := true
+ for i := 0; i < 15; i++ {
+ if daemonExist && daemonPid != 0 {
+ exist, err := process.PidExists(int32(daemonPid))
+ if err != nil {
+ logs.WithError(err).Errorf("check daemon process exist failed, pid: %d", daemonPid)
+ }
+ daemonExist = exist
+ }
+ if agentExist && agentPid != 0 {
+ exist, err := process.PidExists(int32(agentPid))
+ if err != nil {
+ logs.WithError(err).Errorf("check agent process exist failed, pid: %d", agentPid)
+ }
+ agentExist = exist
+ }
+ if (!daemonChange || !daemonExist) && !agentExist {
+ logs.Infof("wait %d seconds for agent to stop done", i+1)
+ break
+ } else if i == 14 {
+ logs.Errorf("upgrade daemon exist %t, agent exist %t, can't upgrade", !daemonChange || !daemonExist, agentExist)
+ return nil
+ }
+ logs.Infof("wait %d seconds for agent to stop", i+1)
+ time.Sleep(1 * time.Second)
+ }
+
+ // 替换更新文件
+ if agentChange {
+ err = replaceAgentFile(config.GetClienAgentFile())
+ if err != nil {
+ logs.WithError(err).Error("replace agent file failed")
+ }
+ }
+ if daemonChange {
+ err = replaceAgentFile(config.GetClientDaemonFile())
+ if err != nil {
+ logs.WithError(err).Error("replace daemon file failed")
+ }
+ }
+
+ // 只有 daemon 被杀才启动,没被杀等待被 daemon 拉起来
+ if daemonChange {
+ switch startT {
+ case taskStart:
+ cmd := exec.Command("cmd.exe", "/c", systemutil.GetWorkDir()+"/devopsctl.vbs")
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ CreationFlags: constant.WinCommandNewConsole | syscall.CREATE_NEW_PROCESS_GROUP,
+ NoInheritHandles: true,
+ }
+ if _, err = winTask.Run(); err != nil {
+ return errors.Wrapf(err, "start win task failed")
+ }
+ }
+ }
+
+ logs.Info("agent upgrade done, upgrade process exiting")
+ return nil
+}
+
+func tryKillAgentProcess(processName string) (int, error) {
+ logs.Info(fmt.Sprintf("try kill %s process", processName))
+ pidFile := fmt.Sprintf("%s/%s.pid", systemutil.GetRuntimeDir(), processName)
+ agentPid, err := fileutil.GetString(pidFile)
+ if err != nil {
+ logs.Warn(fmt.Sprintf("parse %s pid failed: %s", processName, err))
+ return 0, err
+ }
+ intPid, err := strconv.Atoi(agentPid)
+ if err != nil {
+ logs.Warn(fmt.Sprintf("parse %s pid: %s failed", processName, agentPid))
+ return intPid, err
+ }
+
+ p, err := process.NewProcess(int32(intPid))
+ if err != nil {
+ if errors.Is(err, process.ErrorProcessNotRunning) {
+ return intPid, nil
+ }
+ return intPid, errors.Wrapf(err, "get process %d failed", intPid)
+ }
+
+ if err := p.Kill(); err != nil {
+ return intPid, errors.Wrapf(err, "kill process %d failed", intPid)
+ }
+
+ return intPid, nil
+}
+
+func DoUninstallAgent() error {
+ err := UninstallAgent()
+ if err != nil {
+ logs.WithError(err).Error("uninstall agent failed")
+ return errors.New("uninstall agent failed")
+ }
+ return nil
+}
+
+func UninstallAgent() error {
+ logs.Info("start uninstall agent")
+
+ workDir := systemutil.GetWorkDir()
+ startCmd := workDir + "/" + config.GetUninstallScript()
+ output, err := command.RunCommand(startCmd, []string{} /*args*/, workDir, nil)
+ if err != nil {
+ logs.Error("run uninstall script failed: ", err.Error())
+ logs.Error("output: ", string(output))
+ return errors.New("run uninstall script failed")
+ }
+ logs.Info("output: ", string(output))
+ return nil
+}
+
+func checkUpgradeFileChange(fileName string) (change bool, err error) {
+ oldMd5, err := fileutil.GetFileMd5(systemutil.GetWorkDir() + "/" + fileName)
+ if err != nil {
+ logs.Error(fmt.Sprintf("agentUpgrade|check %s md5 failed", fileName), err)
+ return false, errors.New("check old md5 failed")
+ }
+
+ newMd5, err := fileutil.GetFileMd5(systemutil.GetUpgradeDir() + "/" + fileName)
+ if err != nil {
+ logs.Error(fmt.Sprintf("agentUpgrade|check %s md5 failed", fileName), err)
+ return false, errors.New("check new md5 failed")
+ }
+
+ return oldMd5 != newMd5, nil
+}
+
+func replaceAgentFile(fileName string) error {
+ logs.Info("replace agent file: ", fileName)
+ src := systemutil.GetUpgradeDir() + "/" + fileName
+ dst := systemutil.GetWorkDir() + "/" + fileName
+
+ // 查询 dst 的状态,如果没有的话使用预设权限
+ var perm os.FileMode = 0600
+ if stat, err := os.Stat(dst); err != nil {
+ logs.WithError(err).Warnf("replaceAgentFile %s stat error", dst)
+ } else if stat != nil {
+ perm = stat.Mode()
+ }
+ logs.Infof("replaceAgentFile dst file permissions: %v", perm)
+
+ srcFile, err := os.Open(src)
+ if err != nil {
+ return errors.Wrapf(err, "replaceAgentFile open %s error", src)
+ }
+
+ if err := innerFileUtil.AtomicWriteFile(dst, srcFile, perm); err != nil {
+ return errors.Wrapf(err, "replaceAgentFile AtomicWriteFile %s error", dst)
+ }
+
+ return nil
+}
+
+func findService(name string) bool {
+ m, err := mgr.Connect()
+ if err != nil {
+ logs.WithError(err).Error("connect manager failed")
+ return false
+ }
+ defer m.Disconnect()
+
+ service, err := m.OpenService(name)
+ if err != nil {
+ logs.WithError(err).Error("open manager failed")
+ return false
+ }
+ defer service.Close()
+
+ return true
+}
+
+func findTask(name string) (*taskmaster.RegisteredTask, bool) {
+ service, err := taskmaster.Connect()
+ if err != nil {
+ logs.WithError(err).Error("connect taskmaster failed")
+ return nil, false
+ }
+
+ task, err := service.GetRegisteredTask("\\" + name)
+ if err != nil && !strings.Contains(err.Error(), "error parsing registered task") {
+ logs.WithError(err).Error("get registered task failed")
+ return nil, false
+ }
+
+ return &task, true
+}
diff --git a/src/agent/agent/src/pkg/util/command/command.go b/src/agent/agent/src/pkg/util/command/command.go
index b395eec0479..3503f382f70 100644
--- a/src/agent/agent/src/pkg/util/command/command.go
+++ b/src/agent/agent/src/pkg/util/command/command.go
@@ -28,8 +28,8 @@
package command
import (
- "errors"
"fmt"
+ "github.com/pkg/errors"
"os"
"os/exec"
@@ -85,9 +85,9 @@ func StartProcess(command string, args []string, workDir string, envMap map[stri
}
}
- err := setUser(cmd, runUser)
+ err := SetUser(cmd, runUser)
if err != nil {
- logs.Error("set user failed: ", err.Error())
+ logs.WithError(err).Error("set user failed")
return -1, errors.New(
fmt.Sprintf("%s, Please check [devops.slave.user] in the {agent_dir}/.agent.properties", err.Error()))
}
diff --git a/src/agent/agent/src/pkg/util/command/user.go b/src/agent/agent/src/pkg/util/command/user.go
index cb20e752865..9d54e1a6d3f 100644
--- a/src/agent/agent/src/pkg/util/command/user.go
+++ b/src/agent/agent/src/pkg/util/command/user.go
@@ -31,8 +31,8 @@
package command
import (
- "errors"
"fmt"
+ "github.com/pkg/errors"
"os/exec"
"os/user"
"strconv"
@@ -48,7 +48,7 @@ var envHome = "HOME"
var envUser = "USER"
var envLogName = "LOGNAME"
-func setUser(cmd *exec.Cmd, runUser string) error {
+func SetUser(cmd *exec.Cmd, runUser string) error {
if len(runUser) == 0 { // 传空则直接返回
return nil
@@ -77,7 +77,7 @@ func setUser(cmd *exec.Cmd, runUser string) error {
rUser, err := user.Lookup(runUser)
if err != nil {
- logs.Error("user lookup failed, user: -", runUser, "-, error: ", err.Error())
+ logs.WithError(err).Error("user lookup failed, user: -", runUser, "-, error")
return errors.New("user lookup failed, user: " + runUser)
}
uid, _ := strconv.Atoi(rUser.Uid)
diff --git a/src/agent/agent/src/pkg/util/command/user_win.go b/src/agent/agent/src/pkg/util/command/user_win.go
index d37f9aca68f..b1e502fb492 100644
--- a/src/agent/agent/src/pkg/util/command/user_win.go
+++ b/src/agent/agent/src/pkg/util/command/user_win.go
@@ -36,7 +36,7 @@ import (
"github.com/TencentBlueKing/bk-ci/agentcommon/logs"
)
-func setUser(_ *exec.Cmd, runUser string) error {
+func SetUser(_ *exec.Cmd, runUser string) error {
logs.Info("set user(windows): ", runUser)
return nil
}
diff --git a/src/agent/agent/src/pkg/util/fileutil/fileutil.go b/src/agent/agent/src/pkg/util/fileutil/fileutil.go
new file mode 100644
index 00000000000..ee608dd7341
--- /dev/null
+++ b/src/agent/agent/src/pkg/util/fileutil/fileutil.go
@@ -0,0 +1,62 @@
+/*
+ * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.
+ *
+ * A copy of the MIT License is included in this file.
+ *
+ *
+ * Terms of the MIT License:
+ * ---------------------------------------------------
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+ * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package fileutil
+
+import (
+ "github.com/TencentBlueKing/bk-ci/agent/internal/third_party/dep/fs"
+ exitcode "github.com/TencentBlueKing/bk-ci/agent/src/pkg/exiterror"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/systemutil"
+ "io"
+ "os"
+ "path/filepath"
+)
+
+func AtomicWriteFile(filename string, reader io.Reader, mode os.FileMode) error {
+ tempFile, err := os.CreateTemp(filepath.Split(filename))
+ if err != nil {
+ exitcode.CheckOsIoError(filename, err)
+ return err
+ }
+ tempName := tempFile.Name()
+
+ if _, err := io.Copy(tempFile, reader); err != nil {
+ tempFile.Close() // return value is ignored as we are already on error path
+ exitcode.CheckOsIoError(filename, err)
+ return err
+ }
+
+ if err := tempFile.Close(); err != nil {
+ return err
+ }
+
+ if err := systemutil.Chmod(tempName, mode); err != nil {
+ return err
+ }
+
+ return fs.RenameWithFallback(tempName, filename)
+}
diff --git a/src/agent/agent/src/pkg/util/httputil/devops.go b/src/agent/agent/src/pkg/util/httputil/devops.go
index 177cfc0a605..41b4ee23064 100644
--- a/src/agent/agent/src/pkg/util/httputil/devops.go
+++ b/src/agent/agent/src/pkg/util/httputil/devops.go
@@ -29,19 +29,15 @@ package httputil
import (
"encoding/json"
- "errors"
+ "github.com/TencentBlueKing/bk-ci/agent/src/pkg/constant"
+ "github.com/TencentBlueKing/bk-ci/agentcommon/logs"
+ "github.com/pkg/errors"
"io"
"net/http"
"os"
- "path/filepath"
-
- "github.com/TencentBlueKing/bk-ci/agent/internal/third_party/dep/fs"
-
- "github.com/TencentBlueKing/bk-ci/agentcommon/logs"
"github.com/TencentBlueKing/bk-ci/agent/src/pkg/config"
- exitcode "github.com/TencentBlueKing/bk-ci/agent/src/pkg/exiterror"
- "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/systemutil"
+ innerFileUtil "github.com/TencentBlueKing/bk-ci/agent/src/pkg/util/fileutil"
"github.com/TencentBlueKing/bk-ci/agentcommon/utils/fileutil"
)
@@ -179,7 +175,7 @@ func DownloadUpgradeFile(url string, headers map[string]string, filepath string)
return "", errors.New("download upgrade file failed")
}
- err = AtomicWriteFile(filepath, resp.Body, 0644)
+ err = innerFileUtil.AtomicWriteFile(filepath, resp.Body, constant.CommonFileModePerm)
if err != nil {
logs.Error("download upgrade file failed", err)
return "", errors.New("download upgrade file failed")
@@ -215,28 +211,3 @@ func writeToFile(file string, content io.Reader) error {
}
return nil
}
-
-func AtomicWriteFile(filename string, reader io.Reader, mode os.FileMode) error {
- tempFile, err := os.CreateTemp(filepath.Split(filename))
- if err != nil {
- exitcode.CheckOsIoError(filename, err)
- return err
- }
- tempName := tempFile.Name()
-
- if _, err := io.Copy(tempFile, reader); err != nil {
- tempFile.Close() // return value is ignored as we are already on error path
- exitcode.CheckOsIoError(filename, err)
- return err
- }
-
- if err := tempFile.Close(); err != nil {
- return err
- }
-
- if err := systemutil.Chmod(tempName, mode); err != nil {
- return err
- }
-
- return fs.RenameWithFallback(tempName, filename)
-}
diff --git a/src/agent/agent/src/pkg/util/httputil/httputil.go b/src/agent/agent/src/pkg/util/httputil/httputil.go
index b6ba6ed56d6..deefefc7e8c 100644
--- a/src/agent/agent/src/pkg/util/httputil/httputil.go
+++ b/src/agent/agent/src/pkg/util/httputil/httputil.go
@@ -31,8 +31,8 @@ import (
"bytes"
"context"
"encoding/json"
- "errors"
"fmt"
+ "github.com/pkg/errors"
"io"
"net/http"
"net/url"
diff --git a/src/agent/agent/src/pkg/util/process/process_exit_group_win.go b/src/agent/agent/src/pkg/util/process/process_exit_group_win.go
new file mode 100644
index 00000000000..2b033e9f389
--- /dev/null
+++ b/src/agent/agent/src/pkg/util/process/process_exit_group_win.go
@@ -0,0 +1,80 @@
+//go:build windows
+// +build windows
+
+/*
+ * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available.
+ *
+ * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
+ *
+ * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license.
+ *
+ * A copy of the MIT License is included in this file.
+ *
+ *
+ * Terms of the MIT License:
+ * ---------------------------------------------------
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+ * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+ * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package process
+
+import (
+ "os"
+ "unsafe"
+
+ "golang.org/x/sys/windows"
+)
+
+// We use this struct to retreive process handle(which is unexported)
+// from os.Process using unsafe operation.
+// Source https://gist.github.com/hallazzang/76f3970bfc949831808bbebc8ca15209
+type process struct {
+ Pid int
+ Handle uintptr
+}
+
+type ProcessExitGroup windows.Handle
+
+func NewProcessExitGroup() (ProcessExitGroup, error) {
+ handle, err := windows.CreateJobObject(nil, nil)
+ if err != nil {
+ return 0, err
+ }
+
+ info := windows.JOBOBJECT_EXTENDED_LIMIT_INFORMATION{
+ BasicLimitInformation: windows.JOBOBJECT_BASIC_LIMIT_INFORMATION{
+ LimitFlags: windows.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE,
+ },
+ }
+ if _, err := windows.SetInformationJobObject(
+ handle,
+ windows.JobObjectExtendedLimitInformation,
+ uintptr(unsafe.Pointer(&info)),
+ uint32(unsafe.Sizeof(info))); err != nil {
+ return 0, err
+ }
+
+ return ProcessExitGroup(handle), nil
+}
+
+func (g ProcessExitGroup) Dispose() error {
+ return windows.CloseHandle(windows.Handle(g))
+}
+
+func (g ProcessExitGroup) AddProcess(p *os.Process) error {
+ return windows.AssignProcessToJobObject(
+ windows.Handle(g),
+ windows.Handle((*process)(unsafe.Pointer(p)).Handle))
+}
diff --git a/src/agent/agent/src/pkg/util/systemutil/systemutil.go b/src/agent/agent/src/pkg/util/systemutil/systemutil.go
index be8f414e2f5..325511dff36 100644
--- a/src/agent/agent/src/pkg/util/systemutil/systemutil.go
+++ b/src/agent/agent/src/pkg/util/systemutil/systemutil.go
@@ -28,8 +28,8 @@
package systemutil
import (
- "errors"
"fmt"
+ "github.com/pkg/errors"
"net"
"net/url"
"os"
@@ -229,7 +229,7 @@ func CheckProcess(name string) bool {
processLock = flock.New(processLockFile)
ok, err := processLock.TryLock()
if err != nil {
- logs.Errorf("failed to get process lock(%s), exit: %v", processLockFile, err)
+ logs.WithError(err).Errorf("failed to get process lock(%s), exit", processLockFile)
return false
}
@@ -240,7 +240,7 @@ func CheckProcess(name string) bool {
totalLock := flock.New(fmt.Sprintf("%s/%s.lock", GetRuntimeDir(), TotalLock))
if err = totalLock.Lock(); err != nil {
- logs.Error("get total lock failed, exit", err.Error())
+ logs.WithError(err).Error("get total lock failed, exit")
return false
}
defer func() {
@@ -248,7 +248,7 @@ func CheckProcess(name string) bool {
}()
if err = fileutil.WriteString(pidFile, fmt.Sprintf("%d", os.Getpid())); err != nil {
- logs.Errorf("failed to save pid file(%s): %v", pidFile, err)
+ logs.WithError(err).Errorf("failed to save pid file(%s)", pidFile)
return false
}
diff --git a/src/agent/common/logs/export.go b/src/agent/common/logs/export.go
index 3f9d6ae7115..6ac5ee7ca61 100644
--- a/src/agent/common/logs/export.go
+++ b/src/agent/common/logs/export.go
@@ -51,3 +51,7 @@ func WithField(key string, value interface{}) *logrus.Entry {
func WithError(err error) *logrus.Entry {
return Logs.WithError(err)
}
+
+func WithErrorNoStack(err error) *logrus.Entry {
+ return Logs.WithField(ErrorNoStackKey, err)
+}
diff --git a/src/agent/common/logs/logs.go b/src/agent/common/logs/logs.go
index 5e0ec83e5ec..52b9b20566d 100644
--- a/src/agent/common/logs/logs.go
+++ b/src/agent/common/logs/logs.go
@@ -7,14 +7,17 @@ import (
"os"
"github.com/sirupsen/logrus"
- log "github.com/sirupsen/logrus"
"gopkg.in/natefinch/lumberjack.v2"
)
-var Logs = log.WithFields(log.Fields{})
+const (
+ ErrorNoStackKey = "error_no_stack_key"
+)
+
+var Logs *logrus.Entry
func Init(filepath string, isDebug bool, logStd bool) error {
- logInfo := log.WithFields(log.Fields{})
+ logInfo := logrus.WithFields(logrus.Fields{})
lumLog := &lumberjack.Logger{
Filename: filepath,
@@ -43,9 +46,9 @@ func Init(filepath string, isDebug bool, logStd bool) error {
return nil
}
-// DebugInit 初始化为debug模式下的log,将日志输出到标准输出流,只是为了单元测试使用
+// UNTestDebugInit DebugInit 初始化为debug模式下的log,将日志输出到标准输出流,只是为了单元测试使用
func UNTestDebugInit() {
- logInfo := log.WithFields(log.Fields{})
+ logInfo := logrus.WithFields(logrus.Fields{})
logInfo.Logger.SetFormatter(&MyFormatter{})
logInfo.Logger.SetOutput(os.Stdout)
logInfo.Logger.SetLevel(logrus.DebugLevel)
@@ -68,6 +71,10 @@ func (m *MyFormatter) Format(entry *logrus.Entry) ([]byte, error) {
b.WriteString(newLog)
for k, v := range entry.Data {
+ if k == ErrorNoStackKey {
+ b.WriteString(fmt.Sprintf("|error: %v", v))
+ continue
+ }
switch v := v.(type) {
case error:
// Otherwise errors are ignored by `encoding/json`
diff --git a/src/backend/ci/build.gradle.kts b/src/backend/ci/build.gradle.kts
index 1ab5dc054c1..cc25687d70b 100644
--- a/src/backend/ci/build.gradle.kts
+++ b/src/backend/ci/build.gradle.kts
@@ -1,3 +1,5 @@
+import java.net.URI
+
plugins {
id("com.tencent.devops.boot") version "0.0.7"
detektCheck
@@ -24,6 +26,11 @@ allprojects {
}
}
+ // 新增maven 仓库
+ repositories {
+ add(maven { url = URI("https://repo.jenkins-ci.org/releases") })
+ }
+
// 版本管理
dependencyManagement {
setApplyMavenExclusions(false)
diff --git a/src/backend/ci/core/artifactory/api-artifactory/src/main/kotlin/com/tencent/devops/artifactory/api/service/OpenArtifactoryResource.kt b/src/backend/ci/core/artifactory/api-artifactory/src/main/kotlin/com/tencent/devops/artifactory/api/service/OpenArtifactoryResource.kt
index 6da9812f062..f7a18e235c5 100644
--- a/src/backend/ci/core/artifactory/api-artifactory/src/main/kotlin/com/tencent/devops/artifactory/api/service/OpenArtifactoryResource.kt
+++ b/src/backend/ci/core/artifactory/api-artifactory/src/main/kotlin/com/tencent/devops/artifactory/api/service/OpenArtifactoryResource.kt
@@ -29,9 +29,9 @@ package com.tencent.devops.artifactory.api.service
import com.tencent.bkrepo.webhook.pojo.payload.node.NodeCreatedEventPayload
import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_BK_TOKEN
-import io.swagger.v3.oas.annotations.tags.Tag
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
+import io.swagger.v3.oas.annotations.tags.Tag
import javax.ws.rs.Consumes
import javax.ws.rs.HeaderParam
import javax.ws.rs.POST
diff --git a/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/resources/OpenArtifactoryResourceImpl.kt b/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/resources/OpenArtifactoryResourceImpl.kt
index df75ae53a0d..48de6cfaf50 100644
--- a/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/resources/OpenArtifactoryResourceImpl.kt
+++ b/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/resources/OpenArtifactoryResourceImpl.kt
@@ -36,6 +36,8 @@ import com.tencent.devops.common.api.util.JsonUtil
import com.tencent.devops.common.client.Client
import com.tencent.devops.common.client.ClientTokenService
import com.tencent.devops.common.web.RestResource
+import com.tencent.devops.common.web.annotation.BkApiPermission
+import com.tencent.devops.common.web.constant.BkApiHandleType
import com.tencent.devops.process.api.service.ServicePipelineRuntimeResource
import org.slf4j.LoggerFactory
import javax.ws.rs.core.Response
@@ -47,6 +49,7 @@ class OpenArtifactoryResourceImpl(
private val client: Client
) : OpenArtifactoryResource {
+ @BkApiPermission([BkApiHandleType.API_OPEN_TOKEN_CHECK])
override fun updateArtifactList(
token: String,
nodeCreatedEventPayload: NodeCreatedEventPayload
diff --git a/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/service/impl/BkRepoArchiveFileServiceImpl.kt b/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/service/impl/BkRepoArchiveFileServiceImpl.kt
index 5c8eb8c38cc..a44a6b2057c 100644
--- a/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/service/impl/BkRepoArchiveFileServiceImpl.kt
+++ b/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/service/impl/BkRepoArchiveFileServiceImpl.kt
@@ -52,6 +52,7 @@ import com.tencent.devops.artifactory.util.BkRepoUtils.toFileDetail
import com.tencent.devops.artifactory.util.BkRepoUtils.toFileInfo
import com.tencent.devops.artifactory.util.DefaultPathUtils
import com.tencent.devops.common.api.constant.CommonMessageCode
+import com.tencent.devops.common.api.constant.KEY_SHA_CONTENT
import com.tencent.devops.common.api.exception.ErrorCodeException
import com.tencent.devops.common.api.exception.RemoteServiceException
import com.tencent.devops.common.api.pojo.Page
@@ -64,6 +65,14 @@ import com.tencent.devops.common.archive.util.MimeUtil
import com.tencent.devops.common.auth.api.AuthPermission
import com.tencent.devops.common.auth.api.AuthResourceType
import com.tencent.devops.common.service.utils.HomeHostUtil
+import com.tencent.devops.process.api.service.ServicePipelineResource
+import org.slf4j.LoggerFactory
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.beans.factory.annotation.Value
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
+import org.springframework.stereotype.Service
+import org.springframework.web.context.request.RequestContextHolder
+import org.springframework.web.context.request.ServletRequestAttributes
import java.io.File
import java.io.OutputStream
import java.net.URLDecoder
@@ -73,13 +82,6 @@ import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import javax.servlet.http.HttpServletResponse
import javax.ws.rs.NotFoundException
-import org.slf4j.LoggerFactory
-import org.springframework.beans.factory.annotation.Autowired
-import org.springframework.beans.factory.annotation.Value
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
-import org.springframework.stereotype.Service
-import org.springframework.web.context.request.RequestContextHolder
-import org.springframework.web.context.request.ServletRequestAttributes
@Service
@Suppress("TooManyFunctions", "MagicNumber", "ComplexMethod")
@@ -93,11 +95,12 @@ class BkRepoArchiveFileServiceImpl @Autowired constructor(
private val dockerRegistry: String? = null
override fun show(userId: String, projectId: String, artifactoryType: ArtifactoryType, path: String): FileDetail {
- val nodeDetail = bkRepoClient.getFileDetail(userId = userId,
+ val nodeDetail = bkRepoClient.getFileDetail(
+ userId = userId,
projectId = projectId,
repoName = BkRepoUtils.getRepoName(artifactoryType),
- path = path)
- ?: throw NotFoundException("file[$projectId|$artifactoryType|$path] not found")
+ path = path
+ ) ?: throw NotFoundException("file[$projectId|$artifactoryType|$path] not found")
return nodeDetail.toFileDetail()
}
@@ -115,7 +118,7 @@ class BkRepoArchiveFileServiceImpl @Autowired constructor(
val pathSplit = file.name.split('.')
val destPath = filePath ?: DefaultPathUtils.randomFileName(pathSplit[pathSplit.size - 1])
val metadata = mutableMapOf()
- metadata["shaContent"] = file.inputStream().use { ShaUtils.sha1InputStream(it) }
+ metadata[KEY_SHA_CONTENT] = file.inputStream().use { ShaUtils.sha1InputStream(it) }
props?.forEach {
metadata[it.key] = it.value!!
}
@@ -266,11 +269,15 @@ class BkRepoArchiveFileServiceImpl @Autowired constructor(
page = page ?: 1,
pageSize = pageSize ?: DEFAULT_PAGE_SIZE,
totalPages = 1,
- records = nodeList.map { buildFileInfo(it) }
+ records = nodeList.map { buildFileInfo(it, getPipelineNames(nodeList), getBuildNums(nodeList)) }
)
}
- private fun buildFileInfo(it: QueryNodeInfo): FileInfo {
+ private fun buildFileInfo(
+ it: QueryNodeInfo,
+ pipelineNameMap: Map,
+ buildNumMap: Map
+ ): FileInfo {
return if (parseArtifactoryType(it.repoName) == ArtifactoryType.IMAGE) {
val (imageName, version) = DefaultPathUtils.getImageNameAndVersion(it.fullPath)
val packageVersion = bkRepoClient.getPackageVersionInfo(
@@ -296,18 +303,22 @@ class BkRepoArchiveFileServiceImpl @Autowired constructor(
)
}
} else {
- buildGenericFileInfo(it)
+ buildGenericFileInfo(it, pipelineNameMap, buildNumMap)
}
}
- private fun buildGenericFileInfo(nodeInfo: QueryNodeInfo): FileInfo {
+ private fun buildGenericFileInfo(
+ nodeInfo: QueryNodeInfo,
+ pipelineNameMap: Map,
+ buildNumMap: Map
+ ): FileInfo {
// 归档插件归档目录时,在目录多归档一个.bkci_pipeline文件, 记录归档目录的信息
return if (nodeInfo.name == ".bkci_pipeline") {
FileInfo(
name = nodeInfo.path.split("/").lastOrNull { it.isNotBlank() } ?: StringPool.ROOT,
- fullName = nodeInfo.name,
- path = nodeInfo.fullPath,
- fullPath = nodeInfo.fullPath,
+ fullName = nodeInfo.path,
+ path = nodeInfo.path,
+ fullPath = nodeInfo.path,
size = nodeInfo.size,
folder = nodeInfo.folder,
properties = nodeInfo.metadata?.map { m -> Property(m.key, m.value.toString()) },
@@ -318,7 +329,7 @@ class BkRepoArchiveFileServiceImpl @Autowired constructor(
} else {
FileInfo(
name = nodeInfo.name,
- fullName = nodeInfo.name,
+ fullName = getFullName(nodeInfo, pipelineNameMap, buildNumMap),
path = nodeInfo.fullPath,
fullPath = nodeInfo.fullPath,
size = nodeInfo.size,
@@ -331,6 +342,64 @@ class BkRepoArchiveFileServiceImpl @Autowired constructor(
}
}
+ private fun getPipelineNames(nodeList: List): Map {
+ val pipelineIds = mutableSetOf()
+ nodeList.filter { it.repoName == REPO_NAME_PIPELINE }.forEach {
+ val paths = it.fullPath.split("/")
+ if (paths.size < 3) {
+ logger.warn("illegal pipeline repo node fullPath: ${it.fullPath}")
+ return@forEach
+ }
+ pipelineIds.add(paths[1])
+ }
+ if (pipelineIds.size == 0) {
+ return emptyMap()
+ }
+ return client.get(ServicePipelineResource::class)
+ .getPipelineNameByIds(nodeList.first().projectId, pipelineIds).data.orEmpty()
+ }
+
+ private fun getBuildNums(nodeList: List): Map {
+ val buildIds = mutableSetOf()
+ nodeList.filter { it.repoName == REPO_NAME_PIPELINE }.forEach {
+ val paths = it.fullPath.split("/")
+ if (paths.size < 3) {
+ logger.warn("illegal pipeline repo node fullPath: ${it.fullPath}")
+ return@forEach
+ }
+ buildIds.add(paths[2])
+ }
+ if (buildIds.size == 0) {
+ return emptyMap()
+ }
+ return client.get(ServicePipelineResource::class)
+ .getBuildNoByBuildIds(buildIds, nodeList.first().projectId).data.orEmpty()
+ }
+
+ private fun getFullName(
+ nodeInfo: QueryNodeInfo,
+ pipelineNameMap: Map,
+ buildNumMap: Map
+ ): String {
+ if (nodeInfo.repoName != REPO_NAME_PIPELINE) {
+ return nodeInfo.fullPath
+ }
+ val paths = nodeInfo.fullPath.split("/")
+ if (paths.size < 3) {
+ logger.warn("illegal pipeline repo node fullPath: ${nodeInfo.fullPath}")
+ return nodeInfo.fullPath
+ }
+ val pipelineId = paths[1]
+ val buildId = paths[2]
+ val pipelineName = pipelineNameMap[pipelineId]
+ val buildNum = buildNumMap[buildId]
+ if (pipelineName.isNullOrEmpty() || buildNum.isNullOrEmpty()) {
+ logger.warn("illegal pipelineId or buildId: $pipelineId, $buildId")
+ return nodeInfo.fullPath
+ }
+ return nodeInfo.fullPath.replace("/$pipelineId/$buildId", "/$pipelineName/$buildNum")
+ }
+
override fun generateDestPath(
fileType: FileTypeEnum,
projectId: String,
@@ -340,14 +409,18 @@ class BkRepoArchiveFileServiceImpl @Autowired constructor(
): String {
val result = if (FileTypeEnum.BK_CUSTOM == fileType) {
if (customFilePath.isNullOrBlank() || customFilePath.contains("..")) {
- throw ErrorCodeException(errorCode = CommonMessageCode.PARAMETER_IS_NULL,
- params = arrayOf("customFilePath"))
+ throw ErrorCodeException(
+ errorCode = CommonMessageCode.PARAMETER_IS_NULL,
+ params = arrayOf("customFilePath")
+ )
}
customFilePath.removePrefix("/")
} else {
if (pipelineId.isNullOrBlank() || buildId.isNullOrBlank()) {
- throw ErrorCodeException(errorCode = CommonMessageCode.PARAMETER_IS_NULL,
- params = arrayOf("pipelineId or buildId"))
+ throw ErrorCodeException(
+ errorCode = CommonMessageCode.PARAMETER_IS_NULL,
+ params = arrayOf("pipelineId or buildId")
+ )
}
val filePath = if (customFilePath.isNullOrBlank()) {
""
@@ -382,7 +455,8 @@ class BkRepoArchiveFileServiceImpl @Autowired constructor(
projectId = projectId,
filePath = "/$filePath",
artifactoryType = artifactoryType,
- fileChannelType = fileChannelType, fullUrl = fullUrl)
+ fileChannelType = fileChannelType, fullUrl = fullUrl
+ )
}
override fun getFileDownloadUrls(
diff --git a/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/service/impl/DiskArchiveFileServiceImpl.kt b/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/service/impl/DiskArchiveFileServiceImpl.kt
index b4071d0b6d7..dc24eaaf8b3 100644
--- a/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/service/impl/DiskArchiveFileServiceImpl.kt
+++ b/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/service/impl/DiskArchiveFileServiceImpl.kt
@@ -40,6 +40,7 @@ import com.tencent.devops.artifactory.pojo.enums.FileChannelTypeEnum
import com.tencent.devops.artifactory.pojo.enums.FileTypeEnum
import com.tencent.devops.artifactory.util.DefaultPathUtils
import com.tencent.devops.common.api.constant.CommonMessageCode
+import com.tencent.devops.common.api.constant.KEY_SHA_CONTENT
import com.tencent.devops.common.api.exception.ErrorCodeException
import com.tencent.devops.common.api.pojo.Page
import com.tencent.devops.common.api.util.PageUtil
@@ -383,7 +384,7 @@ class DiskArchiveFileServiceImpl : ArchiveFileServiceImpl() {
uploadFileToRepo(destPath, file)
val shaContent = file.inputStream().use { ShaUtils.sha1InputStream(it) }
var fileProps: Map = props ?: mapOf()
- fileProps = fileProps.plus("shaContent" to shaContent)
+ fileProps = fileProps.plus(KEY_SHA_CONTENT to shaContent)
val path = destPath.substring(getBasePath().length)
val fileId = UUIDUtil.generate()
dslContext.transaction { t ->
diff --git a/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/store/service/impl/ArchiveAtomServiceImpl.kt b/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/store/service/impl/ArchiveAtomServiceImpl.kt
index 8fe2080c4b3..cb9e9db4d2e 100644
--- a/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/store/service/impl/ArchiveAtomServiceImpl.kt
+++ b/src/backend/ci/core/artifactory/biz-artifactory/src/main/kotlin/com/tencent/devops/artifactory/store/service/impl/ArchiveAtomServiceImpl.kt
@@ -39,6 +39,7 @@ import com.tencent.devops.artifactory.pojo.PackageFileInfo
import com.tencent.devops.artifactory.pojo.ReArchiveAtomRequest
import com.tencent.devops.artifactory.store.service.ArchiveAtomService
import com.tencent.devops.common.api.constant.CommonMessageCode
+import com.tencent.devops.common.api.constant.KEY_SHA_CONTENT
import com.tencent.devops.common.api.constant.STATIC
import com.tencent.devops.common.api.exception.ErrorCodeException
import com.tencent.devops.common.api.pojo.Result
@@ -214,7 +215,7 @@ abstract class ArchiveAtomServiceImpl : ArchiveAtomService {
dslContext = context,
userId = userId,
fileId = fileId,
- props = mapOf("shaContent" to packageFileInfo.shaContent)
+ props = mapOf(KEY_SHA_CONTENT to packageFileInfo.shaContent)
)
}
}
diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceManagerResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceManagerResource.kt
index f6c1d24c257..c0353028065 100644
--- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceManagerResource.kt
+++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceManagerResource.kt
@@ -30,8 +30,8 @@ package com.tencent.devops.auth.api.service
import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_BK_TOKEN
import com.tencent.devops.common.api.auth.AUTH_HEADER_DEVOPS_USER_ID
import com.tencent.devops.common.api.pojo.Result
-import io.swagger.v3.oas.annotations.tags.Tag
import io.swagger.v3.oas.annotations.Parameter
+import io.swagger.v3.oas.annotations.tags.Tag
import javax.ws.rs.Consumes
import javax.ws.rs.GET
import javax.ws.rs.HeaderParam
diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServicePermissionAuthResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServicePermissionAuthResource.kt
index 76838004fd0..6b7fbc569cd 100644
--- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServicePermissionAuthResource.kt
+++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServicePermissionAuthResource.kt
@@ -34,9 +34,9 @@ import com.tencent.devops.common.api.auth.AUTH_HEADER_GIT_TYPE
import com.tencent.devops.common.api.pojo.Result
import com.tencent.devops.common.auth.api.AuthPermission
import com.tencent.devops.common.auth.api.pojo.AuthResourceInstance
-import io.swagger.v3.oas.annotations.tags.Tag
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
+import io.swagger.v3.oas.annotations.tags.Tag
import javax.ws.rs.Consumes
import javax.ws.rs.DELETE
import javax.ws.rs.GET
diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceProjectAuthResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceProjectAuthResource.kt
index 7bc6c362ff2..2b12f32d915 100644
--- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceProjectAuthResource.kt
+++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceProjectAuthResource.kt
@@ -35,9 +35,9 @@ import com.tencent.devops.common.api.pojo.Result
import com.tencent.devops.common.auth.api.pojo.BKAuthProjectRolesResources
import com.tencent.devops.common.auth.api.pojo.BkAuthGroup
import com.tencent.devops.common.auth.api.pojo.BkAuthGroupAndUserList
-import io.swagger.v3.oas.annotations.tags.Tag
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.Parameter
+import io.swagger.v3.oas.annotations.tags.Tag
import javax.ws.rs.Consumes
import javax.ws.rs.GET
import javax.ws.rs.HeaderParam
@@ -134,6 +134,22 @@ interface ServiceProjectAuthResource {
group: BkAuthGroup? = null
): Result
+ @GET
+ @Path("/{projectCode}/users/{userId}/checkUserInProjectLevelGroup")
+ @Operation(summary = "是否该用户在项目级别的组中")
+ fun checkUserInProjectLevelGroup(
+ @HeaderParam(AUTH_HEADER_DEVOPS_BK_TOKEN)
+ @Parameter(description = "认证token", required = true)
+ token: String,
+ @HeaderParam(AUTH_HEADER_GIT_TYPE)
+ @PathParam("userId")
+ @Parameter(description = "用户Id", required = true)
+ userId: String,
+ @PathParam("projectCode")
+ @Parameter(description = "项目Code", required = true)
+ projectCode: String
+ ): Result
+
@GET
@Path("/{projectCode}/users/{userId}/checkProjectManager")
@Operation(summary = "判断是否是项目管理员")
diff --git a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceResourceGroupResource.kt b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceResourceGroupResource.kt
index 443f652c5b6..dcbc9e6e546 100644
--- a/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceResourceGroupResource.kt
+++ b/src/backend/ci/core/auth/api-auth/src/main/kotlin/com/tencent/devops/auth/api/service/ServiceResourceGroupResource.kt
@@ -1,6 +1,8 @@
package com.tencent.devops.auth.api.service
-import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID
+import com.tencent.devops.auth.pojo.dto.GroupAddDTO
+import com.tencent.devops.auth.pojo.vo.GroupPermissionDetailVo
+import com.tencent.devops.common.api.annotation.BkInterfaceI18n
import com.tencent.devops.common.api.pojo.Result
import com.tencent.devops.common.auth.api.pojo.BkAuthGroup
import io.swagger.v3.oas.annotations.Operation
@@ -8,7 +10,7 @@ import io.swagger.v3.oas.annotations.Parameter
import io.swagger.v3.oas.annotations.tags.Tag
import javax.ws.rs.Consumes
import javax.ws.rs.DELETE
-import javax.ws.rs.HeaderParam
+import javax.ws.rs.GET
import javax.ws.rs.POST
import javax.ws.rs.Path
import javax.ws.rs.PathParam
@@ -21,13 +23,23 @@ import javax.ws.rs.core.MediaType
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
interface ServiceResourceGroupResource {
+ @GET
+ @Path("/{projectCode}/{groupId}/getGroupPermissionDetail")
+ @Operation(summary = "查询用户组权限详情")
+ @BkInterfaceI18n(keyPrefixNames = ["{data[*].actionId}"], responseDataCacheFlag = true)
+ fun getGroupPermissionDetail(
+ @Parameter(description = "项目Id", required = true)
+ @PathParam("projectCode")
+ projectCode: String,
+ @Parameter(description = "用户组ID")
+ @PathParam("groupId")
+ groupId: Int
+ ): Result