添加common-api和ci-worker部分

This commit is contained in:
geeeekegeeeeke 2025-03-25 10:25:03 +08:00
parent df804de7d2
commit 02f08b6532
87 changed files with 5810 additions and 43 deletions

1
.idea/.gitignore generated vendored
View File

@ -1,5 +1,6 @@
# Default ignored files
/shelf/
../.idea
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

22
.idea/compiler.xml generated
View File

@ -3,15 +3,20 @@
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
</profile>
<profile name="Annotation profile for ops-pro" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<processorPath useClasspath="false">
<entry name="$MAVEN_REPOSITORY$/org/springframework/boot/spring-boot-configuration-processor/3.3.4/spring-boot-configuration-processor-3.3.4.jar" />
<entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.34/lombok-1.18.34.jar" />
<entry name="$MAVEN_REPOSITORY$/org/mapstruct/mapstruct-processor/1.6.2/mapstruct-processor-1.6.2.jar" />
<entry name="$MAVEN_REPOSITORY$/org/mapstruct/mapstruct/1.6.2/mapstruct-1.6.2.jar" />
<entry name="$PROJECT_DIR$/../repo/org/springframework/boot/spring-boot-configuration-processor/3.3.4/spring-boot-configuration-processor-3.3.4.jar" />
<entry name="$PROJECT_DIR$/../repo/org/projectlombok/lombok/1.18.34/lombok-1.18.34.jar" />
<entry name="$PROJECT_DIR$/../repo/org/mapstruct/mapstruct-processor/1.6.2/mapstruct-processor-1.6.2.jar" />
<entry name="$PROJECT_DIR$/../repo/org/mapstruct/mapstruct/1.6.2/mapstruct-1.6.2.jar" />
</processorPath>
<module name="ci-scm-repository" />
<module name="spring-boot-starter-protection" />
@ -46,15 +51,9 @@
<module name="spring-boot-starter-redis" />
<module name="spring-boot-starter-security" />
</profile>
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
</profile>
</annotationProcessing>
<bytecodeTargetLevel>
<module name="ci-process-api" target="17" />
<module name="ci-process-base" target="17" />
<module name="ci-worker" target="1.8" />
</bytecodeTargetLevel>
</component>
<component name="JavacSettings">
@ -69,6 +68,7 @@
<module name="ci-quality" options="-parameters" />
<module name="ci-scm-repository" options="-parameters" />
<module name="ci-ticket" options="-parameters" />
<module name="ci-worker" options="-parameters" />
<module name="commons" options="-parameters" />
<module name="framework" options="-parameters" />
<module name="module-infra-api" options="-parameters" />

2
.idea/encodings.xml generated
View File

@ -59,6 +59,8 @@
<file url="file://$PROJECT_DIR$/modules/ci-scm-repository/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/modules/ci-ticket/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/modules/ci-ticket/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/modules/ci-worker/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/modules/ci-worker/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/modules/module-infra-api/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/modules/module-infra-api/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/modules/module-infra-biz/src/main/java" charset="UTF-8" />

1
.idea/gradle.xml generated
View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>

View File

@ -1,14 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="huaweicloud" />
<option name="name" value="huawei" />
<option name="url" value="https://maven.aliyun.com/repository/public" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="aliyunmaven" />
<option name="name" value="aliyun" />
<option name="url" value="https://maven.aliyun.com/repository/public" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
@ -17,19 +27,49 @@
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
<option name="id" value="aliyunmaven" />
<option name="name" value="aliyun" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://maven.aliyun.com/repository/public" />
</remote-repository>
<remote-repository>
<option name="id" value="huaweicloud" />
<option name="name" value="huawei" />
<option name="url" value="https://mirrors.huaweicloud.com/repository/maven/" />
</remote-repository>
<remote-repository>
<option name="id" value="aliyunmaven" />
<option name="name" value="aliyun" />
<option name="url" value="https://maven.aliyun.com/repository/central" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="huaweicloud" />
<option name="name" value="huawei" />
<option name="url" value="https://maven.aliyun.com/repository/central" />
</remote-repository>
<remote-repository>
<option name="id" value="huaweicloud" />
<option name="name" value="huawei" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="https://maven.aliyun.com/repository/public" />
<option name="url" value="https://maven.aliyun.com/repository/central" />
</remote-repository>
</component>
</project>

3
.idea/misc.xml generated
View File

@ -36,10 +36,11 @@
<option value="$PROJECT_DIR$/pom.xml" />
<option value="$PROJECT_DIR$/modules/pipeline-ci-process/pipeline-ci-process-api/pom.xml" />
<option value="$PROJECT_DIR$/modules/ci-process/pipeline-ci-process-api/pom.xml" />
<option value="$PROJECT_DIR$/modules/ci-worker/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" project-jdk-name="22" project-jdk-type="JavaSDK" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK" />
<component name="SuppressionsComponent">
<option name="suppComments" value="[]" />
</component>

View File

@ -18,6 +18,7 @@
<sqlite.version>3.47.1.0</sqlite.version>
<mybatis.version>3.5.16</mybatis.version>
<opentracing.version>0.33.0</opentracing.version>
<caffeine.version>2.9.3</caffeine.version>
<kingbase.jdbc.version>8.6.0</kingbase.jdbc.version>
<commons-compress.version>1.27.1</commons-compress.version>
<rocketmq-spring.version>2.3.1</rocketmq-spring.version>
@ -26,19 +27,27 @@
<redisson.version>3.36.0</redisson.version>
<pf4j-spring.version>0.9.0</pf4j-spring.version>
<transmittable-thread-local.version>2.14.5</transmittable-thread-local.version>
<dd-plist.version>1.28</dd-plist.version>
<spring.boot.version>3.3.4</spring.boot.version>
<bcprov-jdk18on.version>1.80</bcprov-jdk18on.version>
<springdoc.version>2.3.0</springdoc.version>
<version-number.version>1.12</version-number.version>
<lock4j.version>2.2.7</lock4j.version>
<commons-io.version>2.17.0</commons-io.version>
<logback-core.version>1.2.11</logback-core.version>
<apk-parser.version>2.6.10</apk-parser.version>
<hutool-6.version>6.0.0-M16</hutool-6.version>
<resilience4j-circuitbreaker.version>2.3.0</resilience4j-circuitbreaker.version>
<jsoup.version>1.18.1</jsoup.version>
<mybatis-plus.version>3.5.8</mybatis-plus.version>
<knife4j.version>4.5.0</knife4j.version>
<lombok.version>1.18.34</lombok.version>
<skywalking.version>9.0.0</skywalking.version>
<mockito-inline.version>5.2.0</mockito-inline.version>
<logback-classic.version>1.2.11</logback-classic.version>
<commons-exec.version>1.4.0</commons-exec.version>
<velocity.version>2.4</velocity.version>
<reflections.version>0.10.2</reflections.version>
<bizlog-sdk.version>3.0.6</bizlog-sdk.version>
<anwena.version>2.0.8.3</anwena.version>
<pf4j.version>3.12.1</pf4j.version>
@ -47,6 +56,7 @@
<hutool-5.version>5.8.32</hutool-5.version>
<revision>2.0.0-jdk17</revision>
<jsch.version>0.1.55</jsch.version>
<winp.version>1.28</winp.version>
<postgresql.version>42.7.4</postgresql.version>
<spring-boot-admin.version>3.3.3</spring-boot-admin.version>
<oracle.version>23.5.0.24.07</oracle.version>
@ -184,18 +194,48 @@
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cd.casic.pipeline</groupId>
<artifactId>pipeline-ci-commons</artifactId>
<groupId>cd.casic.ci</groupId>
<artifactId>ci-commons</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cd.casic.pipeline</groupId>
<artifactId>pipeline-ci-event</artifactId>
<groupId>cd.casic.ci</groupId>
<artifactId>ci-event</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cd.casic.pipeline</groupId>
<artifactId>pipeline-ci-log</artifactId>
<groupId>cd.casic.ci</groupId>
<artifactId>ci-log</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cd.casic.ci</groupId>
<artifactId>ci-market</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cd.casic.ci</groupId>
<artifactId>ci-process</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cd.casic.ci</groupId>
<artifactId>ci-project</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cd.casic.ci</groupId>
<artifactId>ci-quality</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cd.casic.ci</groupId>
<artifactId>ci-ticket</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cd.casic.ci</groupId>
<artifactId>ci-scm-repository</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
@ -204,8 +244,8 @@
<version>${bizlog-sdk.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
@ -260,12 +300,12 @@
<version>${easy-trans.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
<groupId>org.springframework.cloud</groupId>
</exclusion>
</exclusions>
</dependency>
@ -285,8 +325,8 @@
<version>${redisson.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
@ -296,8 +336,8 @@
<version>${lock4j.version}</version>
<exclusions>
<exclusion>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<groupId>org.redisson</groupId>
</exclusion>
</exclusions>
</dependency>
@ -337,8 +377,8 @@
<version>${spring-boot-admin.version}</version>
<exclusions>
<exclusion>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-cloud</artifactId>
<groupId>de.codecentric</groupId>
</exclusion>
</exclusions>
</dependency>
@ -358,12 +398,12 @@
<version>${spring.boot.version}</version>
<exclusions>
<exclusion>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<groupId>org.ow2.asm</groupId>
</exclusion>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<groupId>org.mockito</groupId>
</exclusion>
</exclusions>
</dependency>
@ -483,8 +523,8 @@
<version>${pf4j.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
@ -533,6 +573,56 @@
<artifactId>bcprov-jdk18on</artifactId>
<version>${bcprov-jdk18on.version}</version>
</dependency>
<dependency>
<groupId>org.jvnet.winp</groupId>
<artifactId>winp</artifactId>
<version>${winp.version}</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci</groupId>
<artifactId>version-number</artifactId>
<version>${version-number.version}}</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>${reflections.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-exec</artifactId>
<version>${commons-exec.version}</version>
</dependency>
<dependency>
<groupId>com.googlecode.plist</groupId>
<artifactId>dd-plist</artifactId>
<version>${dd-plist.version}</version>
</dependency>
<dependency>
<groupId>net.dongliu</groupId>
<artifactId>apk-parser</artifactId>
<version>${apk-parser.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback-core.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-classic.version}</version>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>${caffeine.version}</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-circuitbreaker</artifactId>
<version>${resilience4j-circuitbreaker.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@ -21,14 +21,190 @@
</description>
<dependencies>
<dependency>
<groupId>cd.casic.boot</groupId>
<artifactId>commons</artifactId>
</dependency>
<!-- <dependency>
<groupId>cd.casic.ci</groupId>
<artifactId>ci-commons</artifactId>
</dependency>-->
<dependency>
<groupId>cd.casic.boot</groupId>
<artifactId>spring-boot-starter-mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- javax.ws.rs:javax.ws.rs-api -->
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0</version>
</dependency>
<!-- io.swagger.core.v3:swagger-annotations -->
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<version>2.2.16</version>
</dependency>
<!-- org.hashids:hashids -->
<dependency>
<groupId>org.hashids</groupId>
<artifactId>hashids</artifactId>
<version>1.0.3</version>
</dependency>
<!-- com.fasterxml.jackson.module:jackson-module-kotlin -->
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version>2.13.4</version>
</dependency>
<!-- com.fasterxml.jackson.core:jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.4.2</version>
</dependency>
<!-- com.fasterxml.jackson.core:jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.4</version>
</dependency>
<!-- com.fasterxml.jackson.core:jackson-annotations -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.13.4</version>
</dependency>
<!-- com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider -->
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.13.4</version>
</dependency>
<!-- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.13.4</version>
</dependency>
<!-- com.fasterxml.jackson.jaxrs:jackson-jaxrs-base -->
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-base</artifactId>
<version>2.13.4</version>
</dependency>
<!-- org.bouncycastle:bcprov-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
<!-- com.github.fge:json-schema-validator -->
<dependency>
<groupId>com.github.fge</groupId>
<artifactId>json-schema-validator</artifactId>
<version>2.2.6</version>
</dependency>
<!-- com.google.guava:guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<!-- com.squareup.okhttp3:okhttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.0</version>
</dependency>
<!-- commons-codec:commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
<!-- org.springframework.boot:spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- org.apache.commons:commons-compress -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
</dependency>
<!-- org.apache.commons:commons-exec -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-exec</artifactId>
</dependency>
<!-- org.apache.commons:commons-collections4 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<!-- javax.servlet:javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- javax.validation:validation-api -->
<!-- <dependency>-->
<!-- <groupId>javax.validation</groupId>-->
<!-- <artifactId>validation-api</artifactId>-->
<!--&lt;!&ndash; <version>2.0.2</version>&ndash;&gt;-->
<!-- </dependency>-->
<!-- com.vdurmont:emoji-java -->
<dependency>
<groupId>com.vdurmont</groupId>
<artifactId>emoji-java</artifactId>
<version>5.1.1</version>
</dependency>
<!-- org.apache.lucene:lucene-core -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>8.11.1</version>
</dependency>
<!-- org.apache.commons:commons-csv -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.8</version>
</dependency>
<!-- com.github.ben-manes.caffeine:caffeine -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<!-- com.fasterxml.jackson.datatype:jackson-datatype-jsr310 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.13.4</version>
</dependency>
<!-- com.jakewharton:disklrucache -->
<dependency>
<groupId>com.jakewharton</groupId>
<artifactId>disklrucache</artifactId>
<version>2.0.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,4 +1,4 @@
package cd.casic.ci.commons.constant;
package cd.casic.ci.commons.commonapi.constant;
/**
* @Classname CommonConstants

View File

@ -1,4 +1,4 @@
package cd.casic.ci.commons.constant;
package cd.casic.ci.commons.commonapi.constant;
/**
* @Classname CommonMessageCode

View File

@ -0,0 +1,57 @@
package cd.casic.ci.commons.commonapi.enums;
import lombok.SneakyThrows;
public enum AgentStatus {
UN_IMPORT(0), // 未导入用户刚刚在界面上面生成链接
UN_IMPORT_OK(1), // 未导入但是agent状态正常这个时候还是不能用来当构建机
IMPORT_OK(2), // 用户已经在界面导入并且agent工作正常构建机只有在这个状态才能正常工作
IMPORT_EXCEPTION(3), // agent异常
DELETE(4);
private final int status;
AgentStatus(int status) {
this.status = status;
}
@Override
public String toString() {
return String.valueOf(status);
}
@SneakyThrows
public static AgentStatus fromStatus(int status) {
for (AgentStatus value : values()) {
if (status == value.status) {
return value;
}
}
throw new Exception("Unknown agent status(" + status + ")");
// throw new InvalidParamException("Unknown agent status(" + status + ")");
}
public static boolean isDelete(AgentStatus status) {
return status == DELETE;
}
public static boolean isUnImport(AgentStatus status) {
return status == UN_IMPORT;
}
public static boolean isImportException(AgentStatus status) {
return status == IMPORT_EXCEPTION;
}
@SneakyThrows
public static AgentStatus fromString(String status) {
for (AgentStatus value : values()) {
if (status.equals(value.name())) {
return value;
}
}
throw new Exception("Unknown agent status(" + status + ")");
// throw new InvalidParamException("Unknown agent status(" + status + ")");
}
}

View File

@ -0,0 +1,11 @@
package cd.casic.ci.commons.commonapi.enums;
public enum BuildReviewType {
TASK_REVIEW,
STAGE_REVIEW,
QUALITY_TASK_REVIEW_PASS,
QUALITY_TASK_REVIEW_ABORT,
QUALITY_CHECK_IN,
QUALITY_CHECK_OUT,
TRIGGER_REVIEW
}

View File

@ -0,0 +1,6 @@
package cd.casic.ci.commons.commonapi.enums;
public enum BusTypeEnum {
PIPELINE,
TEMPLATE
}

View File

@ -0,0 +1,24 @@
package cd.casic.ci.commons.commonapi.enums;
import org.apache.commons.lang3.StringUtils;
public enum CheckoutRepositoryType {
ID,
NAME,
URL,
SELF;
public static CheckoutRepositoryType parseType(String type) {
if (type == null || StringUtils.isBlank(type)) {
return ID;
}
return valueOf(type);
}
/**
* 拉取类型跳过定时触发源代码变更检查
*/
public static boolean skipTimerTriggerChange(String type) {
return type != null && (type.equals(URL.name()) || type.equals(SELF.name()));
}
}

View File

@ -0,0 +1,8 @@
package cd.casic.ci.commons.commonapi.enums;
public enum CrudEnum {
CREATE, // 增加
DELETE, // 删除
UPDATE, // 更新
READ // 查询
}

View File

@ -0,0 +1,41 @@
package cd.casic.ci.commons.commonapi.enums;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ServiceLoader;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* 仅在初始化时调用一次不可重复使用
*/
public class EnumLoader {
private static final AtomicBoolean modify = new AtomicBoolean(false);
private static final Logger logger = LoggerFactory.getLogger(EnumLoader.class);
private EnumLoader() {
// Private constructor to prevent instantiation
}
public static void enumModified() {
// 同一JVM中防止多次重复加载造成Enum实例不一致
if (!modify.compareAndSet(false, true)) {
return;
}
Class<EnumModifier> clazz = EnumModifier.class;
ServiceLoader<EnumModifier> fetcheries = ServiceLoader.load(clazz);
if (!fetcheries.iterator().hasNext()) {
fetcheries = ServiceLoader.load(clazz, ServiceLoader.class.getClassLoader());
}
fetcheries.forEach(modifier -> {
logger.info("[ENUM MODIFIER]: {}", modifier);
try {
modifier.modified();
} catch (Exception e) {
logger.error("[ENUM MODIFIER]| load fail| {}", e.getMessage(), e);
}
});
}
}

View File

@ -0,0 +1,8 @@
package cd.casic.ci.commons.commonapi.enums;
public interface EnumModifier {
/**
* 实现对现有枚举进行注册扩展修改
*/
void modified();
}

View File

@ -0,0 +1,26 @@
package cd.casic.ci.commons.commonapi.enums;
public enum FrontendTypeEnum {
HISTORY("1.0"), // 历史老插件UI
NORMAL("1.1"), // 官方提供典型的插件UI配置方式
SPECIAL("1.2"); // 定制插件UI方式
private final String typeVersion;
FrontendTypeEnum(String typeVersion) {
this.typeVersion = typeVersion;
}
public static FrontendTypeEnum getFrontendTypeObj(String typeVersion) {
for (FrontendTypeEnum enumObj : values()) {
if (enumObj.typeVersion.equals(typeVersion)) {
return enumObj;
}
}
return null;
}
public String getTypeVersion() {
return typeVersion;
}
}

View File

@ -0,0 +1,6 @@
package cd.casic.ci.commons.commonapi.enums;
public enum I18nSourceEnum {
DB, // 来源于数据库
PROPERTIES // 来源于国际化资源文件
}

View File

@ -0,0 +1,6 @@
package cd.casic.ci.commons.commonapi.enums;
public enum I18nTranslateTypeEnum {
NAME, // 基于字段名称进行翻译
VALUE // 基于字段值进行翻译
}

View File

@ -0,0 +1,11 @@
package cd.casic.ci.commons.commonapi.enums;
/**
* Powered By Tencent
*/
public enum OSType {
WINDOWS,
LINUX,
MAC_OS,
OTHER
}

View File

@ -0,0 +1,36 @@
package cd.casic.ci.commons.commonapi.enums;
public enum PlatformEnum {
ANDROID(1, "安卓"),
IOS(2, "IOS");
private final int id;
private final String mean;
PlatformEnum(int id, String mean) {
this.id = id;
this.mean = mean;
}
public static PlatformEnum of(Integer id) {
if (id == null) {
return null;
}
for (PlatformEnum value : values()) {
if (value.id == id) {
return value;
}
}
return null;
}
public int getId() {
return id;
}
public String getMean() {
return mean;
}
}

View File

@ -0,0 +1,15 @@
package cd.casic.ci.commons.commonapi.enums;
import org.apache.commons.lang3.StringUtils;
public enum RepositoryType {
ID,
NAME;
public static RepositoryType parseType(String type) {
if (type == null || StringUtils.isBlank(type)) {
return ID;
}
return valueOf(type);
}
}

View File

@ -0,0 +1,10 @@
package cd.casic.ci.commons.commonapi.enums;
public enum RequestChannelTypeEnum {
USER,
SERVICE,
BUILD,
OP,
OPEN,
API
}

View File

@ -0,0 +1 @@
package cd.casic.ci.commons.commonapi.enums;

View File

@ -0,0 +1,46 @@
package cd.casic.ci.commons.commonapi.enums;
@SuppressWarnings("unused")
public enum SystemModuleEnum {
COMMON("00"), // 公共模块
PROCESS("01"), // 流水线
ARTIFACTORY("02"), // 版本仓库
OPENAPI("12"), // 开放平台API
PLUGIN("13"), // 插件
QUALITY("14"), // 质量红线
REPOSITORY("15"), // 代码库
SCM("16"), // 软件配置管理
SUPPORT("17"), // 支撑服务
TICKET("18"), // 证书凭据
PROJECT("19"), // 项目管理
STORE("20"), // 商店
AUTH("21"), // 权限
SIGN("22"), // 签名服务
METRICS("23"), // 度量服务
EXTERNAL("24"), // 外部扩展
PREBUILD("25"), // 预构建
BUILDLESS("27"), // buildless服务
LAMBDA("28"), // lambda服务
STREAM("29"), // stream服务
WORKER("30"), // 度量服务
REMOTEDEV("32"); // 远程开发服务
private final String code;
SystemModuleEnum(String code) {
this.code = code;
}
public static String getSystemModule(String code) {
for (SystemModuleEnum value : values()) {
if (value.code.equals(code)) {
return value.name();
}
}
return COMMON.name();
}
public String getCode() {
return code;
}
}

View File

@ -0,0 +1,12 @@
package cd.casic.ci.commons.commonapi.enums;
public enum TaskStatusEnum {
INIT,
HANDING,
FAIL,
SUCCESS,
PENDING_ROLLBACK,
ROLLBACKING,
ROLLBACK_SUCCESS,
ROLLBACK_FAIL
}

View File

@ -0,0 +1,25 @@
package cd.casic.ci.commons.commonapi.enums;
import cd.casic.ci.commons.commonapi.enums.RepositoryType;
public enum TriggerRepositoryType {
ID,
NAME,
SELF,
NONE; // 触发器不需要绑定代码库,如定时触发默认时,不需要绑定
public static RepositoryType toRepositoryType(TriggerRepositoryType type) {
if (type == null) {
return null;
}
switch (type) {
case ID:
case SELF:
return RepositoryType.ID;
case NAME:
return RepositoryType.NAME;
default:
return null;
}
}
}

View File

@ -0,0 +1,47 @@
package cd.casic.ci.commons.commonapi.pojo;
import cd.casic.ci.commons.commonapi.enums.AgentStatus;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
@Schema(title = "第三方Agent数据返回包装模型")
public class AgentResult<T> {
@Schema(title = "状态码", required = true)
private final Integer status;
@Schema(title = "错误信息", required = false)
private final String message;
@Schema(title = "Agent状态", required = false)
private final AgentStatus agentStatus;
@Schema(title = "数据", required = false)
private final T data;
public AgentResult(AgentStatus status, T data) {
this(0, null, status, data);
}
public AgentResult(Integer status, String message) {
this(status, message, null, null);
}
@JsonIgnore
public boolean isNotOk() {
return status != 0;
}
@JsonIgnore
public boolean isAgentNotOK() {
return agentStatus == null || isAgentDelete();
}
@JsonIgnore
public boolean isAgentDelete() {
return agentStatus != null && agentStatus == AgentStatus.DELETE;
}
}

View File

@ -0,0 +1,62 @@
package cd.casic.ci.commons.commonapi.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Map;
@Data
@Schema(title = "插件监控数据")
public class AtomMonitorData {
@Schema(title = "插件执行错误码", required = true)
//@InfluxTag
private Integer errorCode;
@Schema(title = "插件执行错误信息", required = false)
private String errorMsg;
@Schema(title = "插件执行错误类型", required = false)
//@InfluxTag
private String errorType;
@Schema(title = "插件代码", required = true)
//@InfluxTag
private String atomCode;
@Schema(title = "插件版本", required = true)
private String version;
@Schema(title = "项目ID", required = true)
private String projectId;
@Schema(title = "流水线ID", required = true)
private String pipelineId;
@Schema(title = "构建ID", required = true)
private String buildId;
@Schema(title = "构建环境ID", required = true)
private String vmSeqId;
@Schema(title = "执行开始时间", required = false)
//@InfluxTag
private Long startTime;
@Schema(title = "执行结束时间", required = false)
//@InfluxTag
private Long endTime;
@Schema(title = "执行耗时时间", required = false)
private Long elapseTime;
@Schema(title = "来源渠道", required = false)
private String channel;
@Schema(title = "执行人", required = true)
private String starter;
@Schema(title = "组织架构详细信息", required = true)
private OrganizationDetailInfo organizationDetailInfo;
@Schema(title = "扩展数据", required = false)
private Map<String, Object> extData;
}

View File

@ -0,0 +1,42 @@
package cd.casic.ci.commons.commonapi.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(title = "构建历史-分页数据包装模型")
public class BuildHistoryPage<T> {
@Schema(title = "总记录行数", required = true)
private final Long count;
@Schema(title = "第几页", required = true)
private final Integer page;
@Schema(title = "每页多少条", required = true)
private final Integer pageSize;
@Schema(title = "总共多少页", required = true)
private final Integer totalPages;
@Schema(title = "数据", required = true)
private final List<T> records;
@Schema(title = "是否拥有下载构建的权限", required = true)
private final Boolean hasDownloadPermission;
@Schema(title = "最新的编排版本号", required = true)
private final Integer pipelineVersion;
public BuildHistoryPage(Integer page, Integer pageSize, Long count, List<T> records,
Boolean hasDownloadPermission, Integer pipelineVersion) {
this.count = count;
this.page = page;
this.pageSize = pageSize;
this.totalPages = (int) Math.ceil(count.doubleValue() / pageSize);
this.records = records;
this.hasDownloadPermission = hasDownloadPermission;
this.pipelineVersion = pipelineVersion;
}
}

View File

@ -0,0 +1,26 @@
package cd.casic.ci.commons.commonapi.pojo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class CommonEnv {
private static final Map<String, String> envMap = new ConcurrentHashMap<>();
private static final Logger logger = LoggerFactory.getLogger(CommonEnv.class);
private CommonEnv() {
// Private constructor to prevent instantiation
}
public static void addCommonEnv(Map<String, String> env) {
logger.info("Add the env({}) to common environment", env);
envMap.putAll(env);
}
public static Map<String, String> getCommonEnv() {
return new HashMap<>(envMap);
}
}

View File

@ -0,0 +1,33 @@
package cd.casic.ci.commons.commonapi.pojo;
public class ErrorCode {
// 蓝盾系统错误
public static final int SYSTEM_DAEMON_INTERRUPTED = 2189500;
public static final int SYSTEM_SERVICE_ERROR = 2189501;
public static final int SYSTEM_OUTTIME_ERROR = 2189502;
public static final int SYSTEM_WORKER_LOADING_ERROR = 2189503;
public static final int SYSTEM_WORKER_INITIALIZATION_ERROR = 2189504;
public static final int SYSTEM_INNER_TASK_ERROR = 2189505;
// 第三方接入平台错误
public static final int THIRD_PARTY_INTERFACE_ERROR = 2199501;
public static final int THIRD_PARTY_BUILD_ENV_ERROR = 2199502;
// 插件执行错误
public static final int PLUGIN_DEFAULT_ERROR = 2199001;
// 用户使用错误
public static final int USER_INPUT_INVAILD = 2199002;
public static final int USER_RESOURCE_NOT_FOUND = 2199003;
public static final int USER_TASK_OPERATE_FAIL = 2199004;
public static final int USER_JOB_OUTTIME_LIMIT = 2199005;
public static final int USER_TASK_OUTTIME_LIMIT = 2199006;
public static final int USER_QUALITY_CHECK_FAIL = 2199007;
public static final int USER_SCRIPT_COMMAND_INVAILD = 2199009;
public static final int USER_STAGE_FASTKILL_TERMINATE = 2199010;
public static final int USER_SCRIPT_TASK_FAIL = 2199011;
private ErrorCode() {
// Private constructor to prevent instantiation
}
}

View File

@ -0,0 +1,35 @@
package cd.casic.ci.commons.commonapi.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(title = "插件错误信息")
public class ErrorInfo {
@Schema(title = "阶段ID", required = false)
private String stageId;
@Schema(title = "作业ID", required = false)
private String containerId;
@Schema(title = "构建矩阵标识", required = false)
private Boolean matrixFlag;
@Schema(title = "插件ID", required = false)
private String taskId;
@Schema(title = "插件名称", required = false)
private String taskName;
@Schema(title = "插件编号", required = false)
private String atomCode;
@Schema(title = "错误类型", required = false)
private Integer errorType;
@Schema(title = "错误码", required = true)
private Integer errorCode;
@Schema(title = "错误信息", required = false)
private String errorMsg;
}

View File

@ -0,0 +1,75 @@
package cd.casic.ci.commons.commonapi.pojo;
public enum ErrorType {
SYSTEM("system", 0),
USER("user", 1),
THIRD_PARTY("thirdParty", 2),
PLUGIN("plugin", 3);
private final String typeName;
private final int num;
ErrorType(String typeName, int num) {
this.typeName = typeName;
this.num = num;
}
public static ErrorType getErrorType(String name) {
if (name == null) {
return null;
}
for (ErrorType type : values()) {
if (type.name().equals(name)) {
return type;
}
}
return null;
}
public static ErrorType getErrorType(Integer ordinal) {
ErrorType result;
if (ordinal == null) {
result = ErrorType.PLUGIN;
} else {
switch (ordinal) {
case 0:
result = ErrorType.SYSTEM;
break;
case 1:
result = ErrorType.USER;
break;
case 2:
result = ErrorType.THIRD_PARTY;
break;
default:
result = ErrorType.PLUGIN;
}
}
return result;
}
/* public static ErrorType getErrorType(Integer ordinal) {
if (ordinal == null) {
return PLUGIN;
}
return switch (ordinal) {
case 0 -> SYSTEM;
case 1 -> USER;
case 2 -> THIRD_PARTY;
default -> PLUGIN;
};
}*/
/* public String getI18n(String language) {
return MessageUtil.getMessageByLocale(
"errorType." + this.typeName,
language
);
}*/
public String getTypeName() {
return typeName;
}
public int getNum() {
return num;
}
}

View File

@ -0,0 +1,17 @@
package cd.casic.ci.commons.commonapi.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(title = "字段国际化信息")
public class FieldLocaleInfo {
@Schema(title = "字段名称")
private String fieldName;
@Schema(title = "字段值")
private String fieldValue;
@Schema(title = "语言信息")
private String language;
}

View File

@ -0,0 +1,23 @@
package cd.casic.ci.commons.commonapi.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(title = "国际化变量")
public class I18Variable {
@Schema(title = "国际化变量名")
private String code;
@Schema(title = "国际化参数")
private List<String> params;
@Schema(title = "默认信息")
private String defaultMessage;
// public String toJsonStr() {
// return JsonUtil.toJson(this, false);
// }
}

View File

@ -0,0 +1,33 @@
package cd.casic.ci.commons.commonapi.pojo;
import cd.casic.ci.commons.commonapi.enums.I18nSourceEnum;
import cd.casic.ci.commons.commonapi.enums.I18nTranslateTypeEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.lang.reflect.Field;
@Data
@Schema(title = "国际化字段信息")
public class I18nFieldInfo {
@Schema(title = "字段")
private Field field;
@Schema(title = "字段所属对象")
private Object entity;
@Schema(title = "翻译信息来源")
private I18nSourceEnum source = I18nSourceEnum.PROPERTIES;
@Schema(title = "翻译类型")
private I18nTranslateTypeEnum translateType = I18nTranslateTypeEnum.NAME;
@Schema(title = "字段前缀名称")
private String keyPrefixName = "";
@Schema(title = "是否复用接口定义的公共前缀")
private boolean reusePrefixFlag = true;
@Schema(title = "字段转换名称")
private String convertName = "";
}

View File

@ -0,0 +1,20 @@
package cd.casic.ci.commons.commonapi.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(title = "国际化信息")
public class I18nMessage {
@Schema(title = "模块标识")
private String moduleCode;
@Schema(title = "国际化语言信息")
private String language;
@Schema(title = "国际化变量名")
private String key;
@Schema(title = "国际化变量值")
private String value;
}

View File

@ -0,0 +1,11 @@
package cd.casic.ci.commons.commonapi.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class IdValue {
private String id;
private String value;
}

View File

@ -0,0 +1,11 @@
package cd.casic.ci.commons.commonapi.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(title = "语言环境信息")
public class LocaleInfo {
@Schema(title = "语言")
private String language;
}

View File

@ -0,0 +1,26 @@
package cd.casic.ci.commons.commonapi.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(title = "返回码详情")
public class MessageCodeDetail {
@Schema(title = "主键ID", required = true)
private String id;
@Schema(title = "信息码", required = true)
private String messageCode;
@Schema(title = "模块代码", required = true)
private String moduleCode;
@Schema(title = "中文简体描述信息", required = true)
private String messageDetailZhCn;
@Schema(title = "中文繁体描述信息", required = false)
private String messageDetailZhTw;
@Schema(title = "英文描述信息", required = false)
private String messageDetailEn;
}

View File

@ -0,0 +1,31 @@
package cd.casic.ci.commons.commonapi.pojo;
public enum OS {
MACOS,
WINDOWS,
LINUX;
public static OS parse(String os) {
// 处理传入的字符串为 null 的情况
if (os == null) {
return null;
}
// 将传入的字符串转换为大写以避免大小写问题
String upperCaseOs = os.toUpperCase();
OS result = null;
switch (upperCaseOs) {
case "MACOS":
result = MACOS;
break;
case "WINDOWS":
result = WINDOWS;
break;
case "LINUX":
result = LINUX;
break;
default:
result = null;
}
return result;
}
}

View File

@ -0,0 +1,26 @@
package cd.casic.ci.commons.commonapi.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(title = "组织架构详细信息")
public class OrganizationDetailInfo {
@Schema(title = "事业群ID")
private Integer bgId;
@Schema(title = "事业群名字")
private String bgName;
@Schema(title = "部门ID")
private Integer deptId;
@Schema(title = "部门名字")
private String deptName;
@Schema(title = "中心ID")
private Integer centerId;
@Schema(title = "中心名字")
private String centerName;
}

View File

@ -0,0 +1,34 @@
package cd.casic.ci.commons.commonapi.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(title = "分页数据包装模型")
public class Page<T> {
@Schema(title = "总记录行数", required = true)
private final Long count;
@Schema(title = "第几页", required = true)
private final Integer page;
@Schema(title = "每页多少条", required = true)
private final Integer pageSize;
@Schema(title = "总共多少页", required = true)
private final Integer totalPages;
@Schema(title = "数据", required = true)
// @BkFieldI18n
private final List<T> records;
public Page(Integer page, Integer pageSize, Long count, List<T> records) {
this.count = count;
this.page = page;
this.pageSize = pageSize;
this.totalPages = (int) Math.ceil(count.doubleValue() / pageSize);
this.records = records;
}
}

View File

@ -0,0 +1,19 @@
package cd.casic.ci.commons.commonapi.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(title = "分页数据包装模型")
public class Pagination<T> {
@Schema(title = "是否有下一页", required = true)
private Boolean hasNext;
@Schema(title = "数据", required = true)
private List<T> records;
@Schema(title = "总记录行数", required = false)
private Long count;
}

View File

@ -0,0 +1,11 @@
package cd.casic.ci.commons.commonapi.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(title = "设置-YAML流水线功能设置")
public class PipelineAsCodeSettings {
@Schema(title = "是否支持YAML流水线功能", required = true)
private Boolean enable = false;
}

View File

@ -0,0 +1,43 @@
package cd.casic.ci.commons.commonapi.pojo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
@Schema(title = "数据返回包装模型")
public class Result<T> {
@Schema(title = "状态码", required = true)
private final Integer status;
@Schema(title = "错误信息", required = false)
private final String message;
@Schema(title = "数据", required = false)
// @BkFieldI18n
private final T data;
public Result(T data) {
this(0, null, data);
}
public Result(String message, T data) {
this(0, message, data);
}
public Result(Integer status, String message) {
this(status, message, null);
}
@JsonIgnore
public boolean isOk() {
return status == 0;
}
@JsonIgnore
public boolean isNotOk() {
return !isOk();
}
}

View File

@ -0,0 +1,30 @@
package cd.casic.ci.commons.commonapi.pojo;
import cd.casic.ci.commons.commonapi.enums.SystemModuleEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(title = "DB分片路由规则")
public class ShardingRoutingRule {
@Schema(title = "集群名称")
private String clusterName;
@Schema(title = "模块标识")
private SystemModuleEnum moduleCode;
@Schema(title = "数据源名称")
private String dataSourceName;
@Schema(title = "数据库表名称")
private String tableName;
@Schema(title = "规则类型")
private ShardingRuleTypeEnum type;
@Schema(title = "路由规则名称")
private String routingName;
@Schema(title = "路由规则值")
private String routingRule;
}

View File

@ -0,0 +1,8 @@
package cd.casic.ci.commons.commonapi.pojo;
public enum ShardingRuleTypeEnum {
DB,
TABLE,
ARCHIVE_DB,
ARCHIVE_TABLE
}

View File

@ -0,0 +1,30 @@
package cd.casic.ci.commons.commonapi.pojo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.Set;
@Data
@Schema(title = "状态")
public class SimpleResult {
@Schema(title = "是否成功", required = true)
private Boolean success;
@Schema(title = "错误信息", required = false)
private String message;
@Schema(title = "错误码信息", required = false)
private Error error;
@Schema(title = "ENV中需要被忽略的调度机器")
private Set<String> ignoreAgentIds;
}
@Data
@Schema(title = "第三方构建信息模型-错误信息")
class Error {
private String errorType;
private String errorMessage;
private Integer errorCode;
}

View File

@ -0,0 +1,25 @@
package cd.casic.ci.commons.commonapi.pojo;
public enum Zone {
DEFAULT("默认"),
SHENZHEN("深圳"),
SHANGHAI("上海"),
CHENGDU("成都"),
TIANJIN("天津"),
GITHUB("GitHub"),
EXTERNAL("外网");
private final String name;
Zone(String name) {
this.name = name;
}
/* public String getI18n(String language) {
return MessageUtil.getMessageByLocale(
"ZONE." + this.name(),
language
);
}*/
}

View File

@ -0,0 +1,39 @@
/*
* 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.
*
* ...
*/
package cd.casic.ci.commons.commonapi.pojo.agent;
public class AgentErrorExitData {
private String errorEnum;
private String message;
public AgentErrorExitData(String errorEnum, String message) {
this.errorEnum = errorEnum;
this.message = message;
}
public String getErrorEnum() {
return errorEnum;
}
public void setErrorEnum(String errorEnum) {
this.errorEnum = errorEnum;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -0,0 +1,59 @@
/*
* 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.
*
* ...
*/
package cd.casic.ci.commons.commonapi.pojo.agent;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
@Schema(title = "Agent属性信息")
public class AgentPropsInfo {
@Schema(title = "agent运行系统的架构信息")
private String arch;
@Schema(title = "jdk版本信息")
private List<String> jdkVersion;
@Schema(title = "docker init 文件升级信息")
private DockerInitFileInfo dockerInitFileInfo;
public AgentPropsInfo(String arch, List<String> jdkVersion, DockerInitFileInfo dockerInitFileInfo) {
this.arch = arch;
this.jdkVersion = jdkVersion;
this.dockerInitFileInfo = dockerInitFileInfo;
}
public String getArch() {
return arch;
}
public void setArch(String arch) {
this.arch = arch;
}
public List<String> getJdkVersion() {
return jdkVersion;
}
public void setJdkVersion(List<String> jdkVersion) {
this.jdkVersion = jdkVersion;
}
public DockerInitFileInfo getDockerInitFileInfo() {
return dockerInitFileInfo;
}
public void setDockerInitFileInfo(DockerInitFileInfo dockerInitFileInfo) {
this.dockerInitFileInfo = dockerInitFileInfo;
}
}

View File

@ -0,0 +1,45 @@
/*
* 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.
*
* ...
*/
package cd.casic.ci.commons.commonapi.pojo.agent;
import io.swagger.v3.oas.annotations.media.Schema;
@Schema(title = "docker init 文件升级信息")
public class DockerInitFileInfo {
@Schema(title = "文件md5值")
private String fileMd5;
@Schema(title = "目前只支持linux机器所以其他系统不需要检查")
private boolean needUpgrade;
public DockerInitFileInfo(String fileMd5, boolean needUpgrade) {
this.fileMd5 = fileMd5;
this.needUpgrade = needUpgrade;
}
public String getFileMd5() {
return fileMd5;
}
public void setFileMd5(String fileMd5) {
this.fileMd5 = fileMd5;
}
public boolean isNeedUpgrade() {
return needUpgrade;
}
public void setNeedUpgrade(boolean needUpgrade) {
this.needUpgrade = needUpgrade;
}
}

View File

@ -0,0 +1,120 @@
/*
* 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.
*
* ...
*/
package cd.casic.ci.commons.commonapi.pojo.agent;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;
@Schema(title = "心跳信息模型")
public class NewHeartbeatInfo {
@Schema(title = "主版本")
private String masterVersion;
@Schema(title = "从属版本")
private String slaveVersion;
@Schema(title = "主机名")
private String hostName;
@Schema(title = "构建机模型")
private String agentIp;
@Schema(title = "并行任务计数")
private int parallelTaskCount;
@Schema(title = "构建机安装路径")
private String agentInstallPath;
@Schema(title = "启动者")
private String startedUser;
@Schema(title = "第三方构建信息列表")
private List<ThirdPartyBuildInfo> taskList;
@Schema(title = "Agent属性信息")
private AgentPropsInfo props;
@Schema(title = "构建机id")
private Long agentId;
@Schema(title = "项目id")
private String projectId;
@Schema(title = "心跳时间戳")
private Long heartbeatTime;
@Schema(title = "忙碌运行中任务数量")
private int busyTaskSize = 0;
@Schema(title = "docker并行任务计数")
private Integer dockerParallelTaskCount;
@Schema(title = "docker构建信息列表")
private List<ThirdPartyDockerBuildInfo> dockerTaskList;
@Schema(title = "忙碌运行docker中任务数量")
private int dockerBusyTaskSize = 0;
@Schema(title = "Agent退出的错误信息")
private AgentErrorExitData errorExitData;
public NewHeartbeatInfo(String masterVersion, String slaveVersion, String hostName, String agentIp,
int parallelTaskCount, String agentInstallPath, String startedUser,
List<ThirdPartyBuildInfo> taskList, AgentPropsInfo props, Long agentId,
String projectId, Long heartbeatTime, int busyTaskSize,
Integer dockerParallelTaskCount, List<ThirdPartyDockerBuildInfo> dockerTaskList,
int dockerBusyTaskSize, AgentErrorExitData errorExitData) {
this.masterVersion = masterVersion;
this.slaveVersion = slaveVersion;
this.hostName = hostName;
this.agentIp = agentIp;
this.parallelTaskCount = parallelTaskCount;
this.agentInstallPath = agentInstallPath;
this.startedUser = startedUser;
this.taskList = taskList;
this.props = props;
this.agentId = agentId;
this.projectId = projectId;
this.heartbeatTime = heartbeatTime;
this.busyTaskSize = busyTaskSize;
this.dockerParallelTaskCount = dockerParallelTaskCount;
this.dockerTaskList = dockerTaskList;
this.dockerBusyTaskSize = dockerBusyTaskSize;
this.errorExitData = errorExitData;
}
public static NewHeartbeatInfo dummyHeartbeat(String projectId, Long agentId) {
return new NewHeartbeatInfo(
"",
"",
"",
"",
0,
"",
"",
List.of(),
new AgentPropsInfo("", null, null),
agentId,
projectId,
System.currentTimeMillis(),
0,
0,
List.of(),
0,
null
);
}
// Getters and Setters
}

View File

@ -0,0 +1,27 @@
package cd.casic.ci.commons.commonapi.pojo.agent;
import io.swagger.v3.oas.annotations.media.Schema;
@Schema(title = "第三方构建信息")
public class ThirdPartyBuildInfo {
@Schema(title = "项目id")
private String projectId;
@Schema(title = "构建id")
private String buildId;
@Schema(title = "构建机编排序号")
private String vmSeqId;
@Schema(title = "工作空间")
private String workspace;
public ThirdPartyBuildInfo(String projectId, String buildId, String vmSeqId, String workspace) {
this.projectId = projectId;
this.buildId = buildId;
this.vmSeqId = vmSeqId;
this.workspace = workspace;
}
// Getters and Setters
}

View File

@ -0,0 +1,35 @@
/*
* 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.
*
* ...
*/
package cd.casic.ci.commons.commonapi.pojo.agent;
import io.swagger.v3.oas.annotations.media.Schema;
@Schema(title = "第三方构建Docker信息")
public class ThirdPartyDockerBuildInfo {
@Schema(title = "项目id")
private String projectId;
@Schema(title = "构建id")
private String buildId;
@Schema(title = "构建机编排序号")
private String vmSeqId;
public ThirdPartyDockerBuildInfo(String projectId, String buildId, String vmSeqId) {
this.projectId = projectId;
this.buildId = buildId;
this.vmSeqId = vmSeqId;
}
// Getters and Setters
}

View File

@ -0,0 +1,39 @@
/*
* 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.
*
* ...
*/
package cd.casic.ci.commons.commonapi.pojo.agent;
import io.swagger.v3.oas.annotations.media.Schema;
@Schema(title = "需要升级的项")
public class UpgradeItem {
@Schema(title = "升级go agent")
private boolean agent;
@Schema(title = "升级worker")
private boolean worker;
@Schema(title = "升级jdk")
private boolean jdk;
@Schema(title = "升级docker init 脚本")
private boolean dockerInitFile;
public UpgradeItem(boolean agent, boolean worker, boolean jdk, boolean dockerInitFile) {
this.agent = agent;
this.worker = worker;
this.jdk = jdk;
this.dockerInitFile = dockerInitFile;
}
// Getters and Setters
}

View File

@ -1,7 +1,5 @@
package cd.casic.ci.commons.constant;
import lombok.NoArgsConstructor;
import lombok.val;
/**
* @author by mianbin
@ -9,7 +7,7 @@ import lombok.val;
* @Description 重要莫动
* @Date 2025/3/19 14:49
*/
@NoArgsConstructor
public final class OpsHeader {
public static final String AUTH_HEADER_USER_ID = "X-DEVOPS-UID";

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cd.casic.boot</groupId>
<artifactId>modules</artifactId>
<version>${revision}</version>
</parent>
<groupId>cd.casic.pipeline</groupId>
<artifactId>ci-environment</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cd.casic.pipeline</groupId>
<artifactId>ci-commons</artifactId>
</dependency>
<dependency>
<groupId>cd.casic.pipeline</groupId>
<artifactId>ci-market</artifactId>
<version>2.0.0-jdk17</version>
</dependency>
<dependency>
<groupId>cd.casic.boot</groupId>
<artifactId>spring-boot-starter-mybatis</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,7 @@
package cd.casic.devops;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

View File

@ -1,11 +1,11 @@
package cd.casic.ci.log.scm.service.github;
import cd.casic.ci.commons.commonapi.constant.CommonMessageCode;
import cd.casic.ci.log.scm.dal.pojo.github.GithubBranch;
import cd.casic.ci.log.scm.dal.pojo.github.GithubTag;
import cd.casic.framework.commons.exception.ServiceException;
import cd.casic.framework.commons.util.http.OkhttpUtils;
import cd.casic.framework.commons.util.retry.RetryUtils;
import cd.casic.ci.commons.constant.CommonMessageCode;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

223
modules/ci-worker/pom.xml Normal file
View File

@ -0,0 +1,223 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cd.casic.boot</groupId>
<artifactId>modules</artifactId>
<version>${revision}</version>
</parent>
<groupId>cd.casic.devops</groupId>
<artifactId>ci-worker</artifactId>
<dependencies>
<!-- < <dependency>-->
<!-- <groupId>cd.casic.devops</groupId>-->
<!-- <artifactId></artifactId>-->
<!-- </dependency>>-->
<!-- <dependency>-->
<!-- <groupId>cd.casic.devops</groupId>-->
<!-- <artifactId>ci-market</artifactId>-->
<!-- <version>2.0.0-jdk17</version>-->
<!-- </dependency>-->
<dependency>
<groupId>cd.casic.ci</groupId>
<artifactId>ci-commons</artifactId>
</dependency>
<dependency>
<groupId>cd.casic.boot</groupId>
<artifactId>spring-boot-starter-mybatis</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons.</artifactId>
</dependency>-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
</dependency>
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
</dependency>
<!-- <dependency>
<groupId>org.jvnet.winp</groupId>
<artifactId>winp</artifactId>
</dependency>-->
<!-- https://mvnrepository.com/artifact/org.jvnet.winp/winp -->
<dependency>
<groupId>org.jvnet.winp</groupId>
<artifactId>winp</artifactId>
<!-- <version>1.28</version>-->
</dependency>
<!-- https://mvnrepository.com/artifact/org.jenkins-ci/version-number -->
<dependency>
<groupId>org.jenkins-ci</groupId>
<artifactId>version-number</artifactId>
<version>1.12</version>
</dependency>
<!-- 外部依赖 -->
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<!-- <version>0.10.2</version>-->
<!-- <version>请替换为实际版本号</version>-->
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-exec</artifactId>
<!-- <version>1.4.0</version>-->
<!-- <version>请替换为实际版本号</version>-->
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<!-- <version>1.21</version>-->
<!-- <version>请替换为实际版本号</version>-->
</dependency>
<dependency>
<groupId>com.googlecode.plist</groupId>
<artifactId>dd-plist</artifactId>
<!-- <version>1.28</version>-->
<!-- <version></version>-->
</dependency>
<dependency>
<groupId>net.dongliu</groupId>
<artifactId>apk-parser</artifactId>
<!-- <version>2.6.10</version>-->
<!-- <version></version>-->
</dependency>
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.36.0.3</version>
<!-- <version></version>-->
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<!-- <version>1.2.11</version>-->
<!-- <version>1</version>-->
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<!-- <version>1.2.11</version>-->
<!-- <version></version>-->
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<!-- <version>2.9.3</version>-->
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-circuitbreaker</artifactId>
<!-- <version>2.3.0</version>-->
<!--
<version></version>-->
</dependency>
<!-- &lt;!&ndash; 内部项目模块依赖 &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>你的项目groupId</groupId>-->
<!-- <artifactId>core:process:api-process</artifactId>-->
<!-- <version>请替换为实际版本号</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>你的项目groupId</groupId>-->
<!-- <artifactId>core:log:api-log</artifactId>-->
<!-- <version>请替换为实际版本号</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>你的项目groupId</groupId>-->
<!-- <artifactId>core:store:api-store</artifactId>-->
<!-- <version>请替换为实际版本号</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>你的项目groupId</groupId>-->
<!-- <artifactId>core:dispatch:api-dispatch</artifactId>-->
<!-- <version>请替换为实际版本号</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>你的项目groupId</groupId>-->
<!-- <artifactId>core:ticket:api-ticket</artifactId>-->
<!-- <version>请替换为实际版本号</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>你的项目groupId</groupId>-->
<!-- <artifactId>core:environment:api-environment</artifactId>-->
<!-- <version>请替换为实际版本号</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>你的项目groupId</groupId>-->
<!-- <artifactId>core:dockerhost:api-dockerhost</artifactId>-->
<!-- <version>请替换为实际版本号</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>你的项目groupId</groupId>-->
<!-- <artifactId>core:common:common-archive</artifactId>-->
<!-- <version>请替换为实际版本号</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>你的项目groupId</groupId>-->
<!-- <artifactId>core:common:common-pipeline</artifactId>-->
<!-- <version>请替换为实际版本号</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>你的项目groupId</groupId>-->
<!-- <artifactId>core:common:common-test</artifactId>-->
<!-- <version>请替换为实际版本号</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>你的项目groupId</groupId>-->
<!-- <artifactId>core:misc:api-image</artifactId>-->
<!-- <version>请替换为实际版本号</version>-->
<!-- <scope>compile</scope>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; 处理 lib 目录下的 jar 包依赖 &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>自定义groupId</groupId>-->
<!-- <artifactId>lib-dependencies</artifactId>-->
<!-- <version>自定义版本号</version>-->
<!-- <scope>system</scope>-->
<!-- <systemPath>${project.basedir}/lib/your-jar-file.jar</systemPath>-->
<!-- </dependency>-->
<!-- 注意:上述 systemPath 需要根据 lib 目录下实际的 jar 包文件名进行调整,
并且使用 system 范围的依赖需要谨慎,因为它可能会导致可移植性问题 -->
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.13.0</version>
</dependency>
<!-- <dependency>
<groupId>org.jenkins-ci</groupId>
<artifactId>version-number</artifactId>
</dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.xerial</groupId>-->
<!-- <artifactId>sqlite-jdbc</artifactId>-->
<!-- </dependency>-->
</dependencies>
</project>

View File

@ -0,0 +1,7 @@
package cd.casic.devops;
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
}
}

View File

@ -0,0 +1,937 @@
/*
* 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 cd.casic.devops.common.process;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.NativeLongByReference;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.jvnet.winp.WinProcess;
import org.jvnet.winp.WinpException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedMap;
import static com.sun.jna.Pointer.NULL;
import static cd.casic.devops.common.process.jna.GNUCLibrary.LIBC;
@SuppressWarnings("all")
public abstract class BkProcessTree implements Iterable<BkProcessTree.OSProcess>, ProcessTreeRemoting.IProcessTree, Serializable {
protected final Map<Integer, BkProcessTree.OSProcess> processes;
private transient volatile List<ProcessKiller> killers;
private static final boolean IS_LITTLE_ENDIAN = "little".equals(System.getProperty("sun.cpu.endian"));
private static final Logger logger = LoggerFactory.getLogger(BkProcessTree.class);
private BkProcessTree() {
this.processes = new HashMap<>();
}
public final BkProcessTree.OSProcess get(int pid) {
return this.processes.get(pid);
}
public final Iterator<BkProcessTree.OSProcess> iterator() {
return this.processes.values().iterator();
}
public abstract BkProcessTree.OSProcess get(Process var1);
public abstract void killAll(Map<String, String> var1, boolean forceFlag) throws InterruptedException;
public static void log(String msg) {
logger.info(msg);
}
public void killAll(Process proc, Map<String, String> modelEnvVars, boolean forceFlag) throws InterruptedException {
log("killAll: process=" + proc + " and envs=" + modelEnvVars);
BkProcessTree.OSProcess p = this.get(proc);
if (p != null) {
p.killRecursively(forceFlag);
}
if (modelEnvVars != null) {
this.killAll(modelEnvVars, forceFlag);
}
}
final List<ProcessKiller> getKillers() throws InterruptedException {
if (this.killers == null) {
this.killers = Collections.emptyList();
}
return this.killers;
}
public static void log(String msg, Throwable e) {
logger.error(msg, e);
}
public static BkProcessTree get() {
try {
if (File.pathSeparatorChar == ';') {
return new BkProcessTree.Windows();
}
String os = Util.fixNull(System.getProperty("os.name"));
switch (os) {
case "Linux":
return new Linux();
case "SunOS":
return new Solaris();
case "Mac OS X":
return new Darwin();
default:
return new Default();
}
} catch (Exception var1) {
log("Failed to load winp. Reverting to the default", var1);
}
return new BkProcessTree.Default();
}
public abstract static class Local extends BkProcessTree {
Local() {
super();
}
}
private static class Default extends BkProcessTree.Local {
public BkProcessTree.OSProcess get(final Process proc) {
return new BkProcessTree.OSProcess(-1) {
public BkProcessTree.OSProcess getParent() {
return null;
}
public void killRecursively(boolean forceFlag) {
proc.destroy();
}
public void kill0(boolean forceFlag) throws InterruptedException {
proc.destroy();
}
public List<String> getArguments() {
return Collections.emptyList();
}
public EnvVars getEnvironmentVariables() {
return new EnvVars();
}
};
}
public void killAll(Map<String, String> modelEnvVars, boolean forceFlag) {
}
}
private static class Darwin extends Unix {
Darwin() {
String arch = System.getProperty("sun.arch.data.model");
// local constants
int sizeOf_kinfo_proc;
int kinfo_proc_pid_offset;
int kinfo_proc_ppid_offset;
if ("64".equals(arch)) {
sizeOf_kinfo_proc = sizeOf_kinfo_proc_64;
kinfo_proc_pid_offset = kinfo_proc_pid_offset_64;
kinfo_proc_ppid_offset = kinfo_proc_ppid_offset_64;
} else {
sizeOf_kinfo_proc = sizeOf_kinfo_proc_32;
kinfo_proc_pid_offset = kinfo_proc_pid_offset_32;
kinfo_proc_ppid_offset = kinfo_proc_ppid_offset_32;
}
try {
NativeLongByReference size = new NativeLongByReference(new NativeLong(0));
Memory m;
int nRetry = 0;
while (true) {
// find out how much memory we need to do this
if (LIBC.sysctl(MIB_PROC_ALL, 3, NULL, size, NULL, new NativeLong(0)) != 0)
throw new IOException("Failed to obtain memory requirement: " + LIBC.strerror(Native.getLastError()));
// now try the real call
m = new Memory(size.getValue().longValue());
if (LIBC.sysctl(MIB_PROC_ALL, 3, m, size, NULL, new NativeLong(0)) != 0) {
if (Native.getLastError() == ENOMEM && nRetry++ < 16)
continue; // retry
throw new IOException("Failed to call kern.proc.all: " + LIBC.strerror(Native.getLastError()));
}
break;
}
int count = size.getValue().intValue() / sizeOf_kinfo_proc;
logger.info("Found {} processes", count);
for (int base = 0; base < size.getValue().intValue(); base += sizeOf_kinfo_proc) {
int pid = m.getInt(base + kinfo_proc_pid_offset);
int ppid = m.getInt(base + kinfo_proc_ppid_offset);
super.processes.put(pid, new DarwinProcess(pid, ppid));
}
} catch (IOException e) {
logger.warn("Failed to obtain process list", e);
}
}
private class DarwinProcess extends UnixProcess {
private final int ppid;
private EnvVars envVars;
private List<String> arguments;
DarwinProcess(int pid, int ppid) {
super(pid);
this.ppid = ppid;
}
@Override
public OSProcess getParent() {
return get(ppid);
}
@Override
public synchronized EnvVars getEnvironmentVariables() {
if (envVars != null)
return envVars;
parse();
return envVars;
}
@Override
public synchronized List<String> getArguments() {
if (arguments != null)
return arguments;
parse();
return arguments;
}
private void parse() {
try {
// allocate them first, so that the parse error wil result in empty data
// and avoid retry.
arguments = new ArrayList<>();
envVars = new EnvVars();
IntByReference argmaxRef = new IntByReference(0);
NativeLongByReference size = new NativeLongByReference(new NativeLong(sizeOfInt));
// for some reason, I was never able to get sysctlbyname work.
// if (LIBC.sysctlbyname("kern.argmax", argmaxRef.getPointer(), size, NULL, _)!=0)
if (LIBC.sysctl(new int[]{CTL_KERN, KERN_ARGMAX}, 2, argmaxRef.getPointer(), size, NULL, new NativeLong(0)) != 0)
throw new IOException("Failed to get kern.argmax: " + LIBC.strerror(Native.getLastError()));
int argmax = argmaxRef.getValue();
class StringArrayMemory extends Memory {
private long offset = 0;
private long length;
StringArrayMemory(long l) {
super(l);
length = l;
}
void setLength(long l) {
length = Math.min(l, size());
}
int readInt() {
if (offset > length - sizeOfInt)
return 0;
int r = getInt(offset);
offset += sizeOfInt;
return r;
}
byte peek() {
if (offset >= length)
return 0;
return getByte(offset);
}
String readString() throws UnsupportedEncodingException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte ch;
while (offset < length && (ch = getByte(offset++)) != '\0')
baos.write(ch);
return baos.toString(StandardCharsets.UTF_8.name());
}
void skip0() {
// skip padding '\0's
while (offset < length && getByte(offset) == '\0')
offset++;
}
}
StringArrayMemory m = new StringArrayMemory(argmax);
m.clear();
size.setValue(new NativeLong(argmax));
if (LIBC.sysctl(new int[]{CTL_KERN, KERN_PROCARGS2, pid}, 3, m, size, NULL, new NativeLong(0)) != 0)
throw new IOException("Failed to obtain ken.procargs2: " + LIBC.strerror(Native.getLastError()));
m.setLength(size.getValue().longValue());
/*
* Make a sysctl() call to get the raw argument space of the
* process. The layout is documented in start.s, which is part
* of the Csu project. In summary, it looks like:
*
* /---------------\ 0x00000000
* : :
* : :
* |---------------|
* | argc |
* |---------------|
* | arg[0] |
* |---------------|
* : :
* : :
* |---------------|
* | arg[argc - 1] |
* |---------------|
* | 0 |
* |---------------|
* | env[0] |
* |---------------|
* : :
* : :
* |---------------|
* | env[n] |
* |---------------|
* | 0 |
* |---------------| <-- Beginning of data returned by sysctl() is here.
* | argc |
* |---------------|
* | exec_path |
* |:::::::::::::::|
* | |
* | String area. |
* | |
* |---------------| <-- Top of stack.
* : :
* : :
* \---------------/ 0xffffffff
*/
// I find the Darwin source code of the 'ps' command helpful in understanding how it does this:
// see https://opensource.apple.com/source/adv_cmds/adv_cmds-176/ps/print.c
int argc = m.readInt();
String args0 = m.readString(); // exec path
m.skip0();
try {
for (int i = 0; i < argc; i++) {
arguments.add(m.readString());
}
} catch (IndexOutOfBoundsException e) {
throw new IllegalStateException("Failed to parse arguments: pid=" + pid + ", arg0=" + args0 + ", arguments=" + arguments + ", nargs=" + argc + ". Please see https://www.jenkins.io/redirect/troubleshooting/darwin-failed-to-parse-arguments", e);
}
// read env vars that follow
while (m.peek() != 0)
envVars.addLine(m.readString());
} catch (IOException e) {
// this happens with insufficient permissions, so just ignore the problem.
}
}
}
private static final int sizeOf_kinfo_proc_32 = 492; // on 32bit Mac OS X.
private static final int sizeOf_kinfo_proc_64 = 648; // on 64bit Mac OS X.
private static final int kinfo_proc_pid_offset_32 = 24;
private static final int kinfo_proc_pid_offset_64 = 40;
private static final int kinfo_proc_ppid_offset_32 = 416;
private static final int kinfo_proc_ppid_offset_64 = 560;
private static final int sizeOfInt = Native.getNativeSize(int.class);
private static final int CTL_KERN = 1;
private static final int KERN_PROC = 14;
private static final int KERN_PROC_ALL = 0;
private static final int ENOMEM = 12;
private static final int[] MIB_PROC_ALL = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
private static final int KERN_ARGMAX = 8;
private static final int KERN_PROCARGS2 = 49;
}
static class Solaris extends BkProcessTree.ProcfsUnix {
Solaris() {
}
protected BkProcessTree.OSProcess createProcess(int pid) throws IOException {
return new BkProcessTree.Solaris.SolarisProcess(pid);
}
private static long to64(int i) {
return (long) i & 4294967295L;
}
private static int adjust(int i) {
return BkProcessTree.IS_LITTLE_ENDIAN ? i << 24 | i << 8 & 16711680 | i >> 8 & '\uff00' | i >>> 24 : i;
}
private class SolarisProcess extends BkProcessTree.UnixProcess {
private final int ppid;
private final int envp;
private final int argp;
private final int argc;
private EnvVars envVars;
private List<String> arguments;
private SolarisProcess(int pid) throws IOException {
super(pid);
try (RandomAccessFile psinfo = new RandomAccessFile(this.getFile("psinfo"), "r")) {
psinfo.seek(8L);
if (Solaris.adjust(psinfo.readInt()) != pid) {
throw new IOException("psinfo PID mismatch");
}
this.ppid = Solaris.adjust(psinfo.readInt());
psinfo.seek(188L);
this.argc = Solaris.adjust(psinfo.readInt());
this.argp = Solaris.adjust(psinfo.readInt());
this.envp = Solaris.adjust(psinfo.readInt());
}
if (this.ppid == -1) {
throw new IOException("Failed to parse PPID from /proc/" + pid + "/status");
}
}
public BkProcessTree.OSProcess getParent() {
return Solaris.this.get(this.ppid);
}
public synchronized List<String> getArguments() {
if (this.arguments == null) {
this.arguments = new ArrayList<>(this.argc);
try (RandomAccessFile as = new RandomAccessFile(this.getFile("as"), "r")) {
BkProcessTree.log("Reading " + this.getFile("as"));
for (int n = 0; n < this.argc; ++n) {
as.seek(Solaris.to64(this.argp + n * 4));
int p = Solaris.adjust(as.readInt());
this.arguments.add(this.readLine(as, p, "argv[" + n + "]"));
}
} catch (IOException var8) {
log(var8.getMessage());
}
this.arguments = Collections.unmodifiableList(this.arguments);
}
return this.arguments;
}
public synchronized EnvVars getEnvironmentVariables() {
if (this.envVars == null) {
this.envVars = new EnvVars();
try (RandomAccessFile as = new RandomAccessFile(this.getFile("as"), "r")) {
BkProcessTree.log("Reading " + this.getFile("as"));
int n = 0;
while (true) {
as.seek(Solaris.to64(this.envp + n * 4));
int p = Solaris.adjust(as.readInt());
if (p == 0) {
break;
}
this.envVars.addLine(this.readLine(as, p, "env[" + n + "]"));
++n;
}
} catch (IOException var8) {
log(var8.getMessage());
}
}
return this.envVars;
}
private String readLine(RandomAccessFile as, int p, String prefix) throws IOException {
BkProcessTree.log("Reading " + prefix + " at " + p);
as.seek(BkProcessTree.Solaris.to64(p));
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int ch;
for (int i = 0; (ch = as.read()) > 0; buf.write(ch)) {
++i;
if (i % 100 == 0) {
BkProcessTree.log(prefix + " is so far " + buf);
}
}
String line = buf.toString();
BkProcessTree.log(prefix + " was " + line);
return line;
}
}
}
static class Linux extends BkProcessTree.ProcfsUnix {
Linux() {
}
protected BkProcessTree.Linux.LinuxProcess createProcess(int pid) throws IOException {
return new BkProcessTree.Linux.LinuxProcess(pid);
}
public byte[] readFileToByteArray(File file) throws IOException {
FileInputStream in = FileUtils.openInputStream(file);
byte[] var3;
try {
var3 = IOUtils.toByteArray(in);
} finally {
in.close();
}
return var3;
}
class LinuxProcess extends BkProcessTree.UnixProcess {
private int ppid = -1;
private EnvVars envVars;
private List<String> arguments;
LinuxProcess(int pid) throws IOException {
super(pid);
try (BufferedReader r = new BufferedReader(new FileReader(this.getFile("status")))) {
String line;
while ((line = r.readLine()) != null) {
line = line.toLowerCase(Locale.ENGLISH);
if (line.startsWith("ppid:")) {
this.ppid = Integer.parseInt(line.substring(5).trim());
break;
}
}
}
if (this.ppid == -1) {
throw new IOException("Failed to parse PPID from /proc/" + pid + "/status");
}
}
public BkProcessTree.OSProcess getParent() {
return Linux.this.get(this.ppid);
}
public synchronized List<String> getArguments() {
if (this.arguments == null) {
this.arguments = new ArrayList<>();
try {
byte[] cmdline = Linux.this.readFileToByteArray(this.getFile("cmdline"));
int pos = 0;
for (int i = 0; i < cmdline.length; ++i) {
byte b = cmdline[i];
if (b == 0) {
this.arguments.add(new String(cmdline, pos, i - pos));
pos = i + 1;
}
}
} catch (IOException var5) {
log(var5.getMessage());
}
this.arguments = Collections.unmodifiableList(this.arguments);
}
return this.arguments;
}
public synchronized EnvVars getEnvironmentVariables() {
if (this.envVars == null) {
this.envVars = new EnvVars();
try {
byte[] environ = Linux.this.readFileToByteArray(this.getFile("environ"));
int pos = 0;
for (int i = 0; i < environ.length; ++i) {
byte b = environ[i];
if (b == 0) {
this.envVars.addLine(new String(environ, pos, i - pos));
pos = i + 1;
}
}
} catch (IOException var5) {
log(var5.getMessage());
}
}
return this.envVars;
}
}
}
private static final class UnixReflection {
private static final Field PID_FIELD;
private static final Method DESTROY_PROCESS;
private UnixReflection() {
}
public static void destroy(int pid, boolean forceFlag) throws IllegalAccessException, InvocationTargetException {
if (isPreJava8()) {
DESTROY_PROCESS.invoke((Object) null, pid);
} else {
DESTROY_PROCESS.invoke((Object) null, pid, forceFlag);
}
}
private static boolean isPreJava8() {
int javaVersionAsAnInteger = Integer.parseInt(System.getProperty("java.version").replaceAll("\\.", "").replaceAll("_", "").substring(0, 2));
return javaVersionAsAnInteger < 18;
}
static {
LinkageError x;
try {
Class<?> clazz = Class.forName("java.lang.UNIXProcess");
PID_FIELD = clazz.getDeclaredField("pid");
PID_FIELD.setAccessible(true);
if (isPreJava8()) {
DESTROY_PROCESS = clazz.getDeclaredMethod("destroyProcess", Integer.TYPE);
} else {
DESTROY_PROCESS = clazz.getDeclaredMethod("destroyProcess", Integer.TYPE, Boolean.TYPE);
}
DESTROY_PROCESS.setAccessible(true);
} catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) {
x = new LinkageError();
x.initCause(e);
throw x;
}
}
}
public abstract class UnixProcess extends BkProcessTree.OSProcess {
protected UnixProcess(int pid) {
super(pid);
}
protected final File getFile(String relativePath) {
return new File(new File("/proc/" + this.getPid()), relativePath);
}
public void kill0(boolean forceFlag) throws InterruptedException {
try {
int pid = this.getPid();
BkProcessTree.log("Killing pid=" + pid);
BkProcessTree.UnixReflection.destroy(pid, forceFlag);
} catch (IllegalAccessException var3) {
IllegalAccessError x = new IllegalAccessError();
x.initCause(var3);
throw x;
} catch (InvocationTargetException var4) {
if (var4.getTargetException() instanceof Error) {
throw (Error) var4.getTargetException();
}
BkProcessTree.log("Failed to terminate pid=" + this.getPid(), var4);
}
}
public void killRecursively(boolean forceFlag) throws InterruptedException {
BkProcessTree.log("Recursively killing pid=" + this.getPid());
for (OSProcess p : this.getChildren()) {
p.killRecursively(forceFlag);
}
this.kill(forceFlag);
}
public abstract List<String> getArguments();
}
abstract static class ProcfsUnix extends BkProcessTree.Unix {
ProcfsUnix() {
File[] processes = (new File("/proc")).listFiles(File::isDirectory);
if (processes == null) {
log("No /proc");
} else {
for (File p : processes) {
int pid;
try {
pid = Integer.parseInt(p.getName());
} catch (NumberFormatException var9) {
continue;
}
try {
this.processes.put(pid, this.createProcess(pid));
} catch (IOException var8) {
log(var8.getMessage());
}
}
}
}
protected abstract BkProcessTree.OSProcess createProcess(int var1) throws IOException;
}
abstract static class Unix extends BkProcessTree.Local {
Unix() {
}
public BkProcessTree.OSProcess get(Process proc) {
try {
return this.get((Integer) BkProcessTree.UnixReflection.PID_FIELD.get(proc));
} catch (IllegalAccessException var4) {
IllegalAccessError x = new IllegalAccessError();
x.initCause(var4);
throw x;
}
}
public void killAll(Map<String, String> modelEnvVars, boolean forceFlag) throws InterruptedException {
for (OSProcess p : this) {
if (p.hasMatchingEnvVars(modelEnvVars)) {
p.killRecursively(forceFlag);
}
}
}
}
private static final class Windows extends BkProcessTree.Local {
Windows() {
for (WinProcess p : WinProcess.all()) {
int pid = p.getPid();
if (pid != 0 && pid != 4) {
super.processes.put(pid, new OSProcess(pid) {
private EnvVars env;
private List<String> args;
public OSProcess getParent() {
return null;
}
public void killRecursively(boolean forceFlag) throws InterruptedException {
BkProcessTree.log("Killing recursively " + this.getPid());
p.killRecursively();
}
public void kill0(boolean forceFlag) throws InterruptedException {
BkProcessTree.log("Killing " + this.getPid());
p.kill();
}
public synchronized List<String> getArguments() {
if (this.args == null) {
this.args = Arrays.asList(QuotedStringTokenizer.tokenize(p.getCommandLine()));
}
return this.args;
}
public synchronized EnvVars getEnvironmentVariables() {
if (this.env == null) {
this.env = new EnvVars();
try {
this.env.putAll(p.getEnvironmentVariables());
} catch (WinpException var2) {
log(var2.getMessage());
}
}
return this.env;
}
});
}
}
}
public BkProcessTree.OSProcess get(Process proc) {
return this.get((new WinProcess(proc)).getPid());
}
public void killAll(Map<String, String> modelEnvVars, boolean forceFlag) throws InterruptedException {
Iterator<BkProcessTree.OSProcess> var2 = this.iterator();
while (true) {
BkProcessTree.OSProcess p;
do {
if (!var2.hasNext()) {
return;
}
p = var2.next();
} while (p.getPid() < 10);
log("Considering to kill " + p.getPid());
boolean matched;
try {
matched = p.hasMatchingEnvVars(modelEnvVars);
} catch (WinpException var6) {
log(" Failed to check environment variable match", var6);
continue;
}
if (matched) {
p.killRecursively(forceFlag);
} else {
log("Environment variable didn't match");
}
}
}
static {
WinProcess.enableDebugPrivilege();
}
}
private final class SerializedProcess implements Serializable {
private final int pid;
private static final long serialVersionUID = 1L;
private SerializedProcess(int pid) {
this.pid = pid;
}
Object readResolve() {
return BkProcessTree.this.get(this.pid);
}
}
public abstract class OSProcess implements ProcessTreeRemoting.IOSProcess, Serializable {
private final Set<Integer> keepAlivePids = new HashSet<>(64);
final int pid;
private OSProcess(int pid) {
this.pid = pid;
}
public final int getPid() {
return this.pid;
}
public final void addKeepAlivePids(Collection<Integer> pids) {
keepAlivePids.addAll(pids);
}
public abstract BkProcessTree.OSProcess getParent();
public final List<BkProcessTree.OSProcess> getChildren() {
List<BkProcessTree.OSProcess> r = new ArrayList<>();
for (OSProcess p : BkProcessTree.this) {
if (p.getParent() == this) {
if (keepAlivePids.contains(p.pid)) {
this.keepAlivePids.add(this.pid);
} else {
p.addKeepAlivePids(keepAlivePids);
r.add(p);
}
}
}
return r;
}
public void kill(boolean forceFlag) throws InterruptedException {
BkProcessTree.log("pid=" + pid + ", iskeepAlive=" + keepAlivePids.contains(pid));
if (!keepAlivePids.contains(pid)) {
kill0(forceFlag);
}
}
public abstract void kill0(boolean forceFlag) throws InterruptedException;
public abstract void killRecursively(boolean forceFlag) throws InterruptedException;
public abstract List<String> getArguments();
public abstract EnvVars getEnvironmentVariables();
public final boolean hasMatchingEnvVars(Map<String, String> modelEnvVar) {
if (!modelEnvVar.isEmpty()) {
SortedMap<String, String> envs = this.getEnvironmentVariables();
Iterator<Entry<String, String>> var3 = modelEnvVar.entrySet().iterator();
Entry<String, String> e;
String v;
do {
if (!var3.hasNext()) {
return true;
}
e = var3.next();
v = envs.get(e.getKey());
} while (v != null && v.equals(e.getValue()));
}
return false;
}
Object writeReplace() {
return BkProcessTree.this.new SerializedProcess(this.pid);
}
}
}

View File

@ -0,0 +1,83 @@
package cd.casic.devops.common.process;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.stream.Collectors;
// copy from jenkins 96a66619b55b3b78b86817798fe36e58b2798cd4
/**
* Traverses a directed graph and if it contains any cycle, throw an exception.
*
* @author Kohsuke Kawaguchi
*/
public abstract class CyclicGraphDetector<N> {
private final Set<N> visited = new HashSet<>();
private final Set<N> visiting = new HashSet<>();
private final Stack<N> path = new Stack<>();
private final List<N> topologicalOrder = new ArrayList<>();
public void run(Iterable<? extends N> allNodes) throws CycleDetectedException {
for (N n : allNodes) {
visit(n);
}
}
/**
* Returns all the nodes in the topologically sorted order.
* That is, if there's an edge a b, b always come earlier than a.
*/
public List<N> getSorted() {
return topologicalOrder;
}
/**
* List up edges from the given node (by listing nodes that those edges point to.)
*
* @return
* Never null.
*/
protected abstract Iterable<? extends N> getEdges(N n);
private void visit(N p) throws CycleDetectedException {
if (!visited.add(p)) return;
visiting.add(p);
path.push(p);
for (N q : getEdges(p)) {
if (q == null) continue; // ignore unresolved references
if (visiting.contains(q))
detectedCycle(q);
visit(q);
}
visiting.remove(p);
path.pop();
topologicalOrder.add(p);
}
private void detectedCycle(N q) throws CycleDetectedException {
int i = path.indexOf(q);
path.push(q);
reactOnCycle(q, path.subList(i, path.size()));
}
/**
* React on detected cycles - default implementation throws an exception.
*/
protected void reactOnCycle(N q, List<N> cycle) throws CycleDetectedException {
throw new CycleDetectedException(cycle);
}
public static final class CycleDetectedException extends Exception {
public final List cycle;
public CycleDetectedException(List cycle) {
super("Cycle detected: " + cycle.stream().map(Object::toString).collect(Collectors.joining(" -> ")));
this.cycle = cycle;
}
}
}

View File

@ -0,0 +1,468 @@
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Red Hat, Inc.
*
* 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 cd.casic.devops.common.process;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.UUID;
import java.util.logging.Logger;
// copy from jenkins 96a66619b55b3b78b86817798fe36e58b2798cd4
/**
* Environment variables.
*
* <p>
* While all the platforms I tested (Linux 2.6, Solaris, and Windows XP) have the case sensitive
* environment variable table, Windows batch script handles environment variable in the case preserving
* but case <b>insensitive</b> way (that is, cmd.exe can get both FOO and foo as environment variables
* when it's launched, and the "set" command will display it accordingly, but "echo %foo%" results in
* echoing the value of "FOO", not "foo" &mdash; this is presumably caused by the behavior of the underlying
* Win32 API {@code GetEnvironmentVariable} acting in case insensitive way.) Windows users are also
* used to write environment variable case-insensitively (like %Path% vs %PATH%), and you can see many
* documents on the web that claims Windows environment variables are case insensitive.
*
* <p>
* So for a consistent cross platform behavior, it creates the least confusion to make the table
* case insensitive but case preserving.
*
* <p>
* In Jenkins, often we need to build up "environment variable overrides"
* on the controller, then to execute the process on agents. This causes a problem
* when working with variables like {@code PATH}. So to make this work,
* we introduce a special convention {@code PATH+FOO} &mdash; all entries
* that starts with {@code PATH+} are merged and prepended to the inherited
* {@code PATH} variable, on the process where a new process is executed.
*
* @author Kohsuke Kawaguchi
*/
public class EnvVars extends TreeMap<String, String> {
private static final long serialVersionUID = 4320331661987259022L;
private static Logger LOGGER = Logger.getLogger(EnvVars.class.getName());
/**
* If this {@link EnvVars} object represents the whole environment variable set,
* not just a partial list used for overriding later, then we need to know
* the platform for which this env vars are targeted for, or else we won't know
* how to merge variables properly.
*
* <p>
* So this property remembers that information.
*/
private Platform platform;
/**
* Gets the platform for which these env vars targeted.
* @since 2.144
* @return The platform.
*/
public Platform getPlatform() {
return platform;
}
/**
* Sets the platform for which these env vars target.
* @since 2.144
* @param platform the platform to set.
*/
public void setPlatform(Platform platform) {
this.platform = platform;
}
public EnvVars() {
super(String.CASE_INSENSITIVE_ORDER);
}
public EnvVars(Map<String, String> m) {
this();
putAll(m);
// because of the backward compatibility, some parts of Jenkins passes
// EnvVars as Map<String,String> so downcasting is safer.
if (m instanceof EnvVars) {
EnvVars lhs = (EnvVars) m;
this.platform = lhs.platform;
}
}
@SuppressWarnings("CopyConstructorMissesField") // does not set #platform, see its Javadoc
public EnvVars(EnvVars m) {
// this constructor is so that in future we can get rid of the downcasting.
this((Map) m);
}
/**
* Builds an environment variables from an array of the form {@code "key","value","key","value"...}
*/
public EnvVars(String... keyValuePairs) {
this();
if (keyValuePairs.length % 2 != 0)
throw new IllegalArgumentException(Arrays.asList(keyValuePairs).toString());
for (int i = 0; i < keyValuePairs.length; i += 2)
put(keyValuePairs[i], keyValuePairs[i + 1]);
}
/**
* Overrides the current entry by the given entry.
*
* <p>
* Handles {@code PATH+XYZ} notation.
*/
public void override(String key, String value) {
if (value == null || value.isEmpty()) {
remove(key);
return;
}
int idx = key.indexOf('+');
if (idx > 0) {
String realKey = key.substring(0, idx);
String v = get(realKey);
if (v == null) v = value;
else {
// we might be handling environment variables for a agent that can have different path separator
// than the controller, so the following is an attempt to get it right.
// it's still more error prone that I'd like.
char ch = platform == null ? File.pathSeparatorChar : platform.pathSeparator;
v = value + ch + v;
}
put(realKey, v);
return;
}
put(key, value);
}
/**
* Overrides all values in the map by the given map.
* See {@link #override(String, String)}.
* @return this
*/
public EnvVars overrideAll(Map<String, String> all) {
for (Map.Entry<String, String> e : all.entrySet()) {
override(e.getKey(), e.getValue());
}
return this;
}
/**
* Calculates the order to override variables.
*
* Sort variables with topological sort with their reference graph.
*
* This is package accessible for testing purpose.
*/
static class OverrideOrderCalculator {
/**
* Extract variables referred directly from a variable.
*/
private static class TraceResolver implements VariableResolver<String> {
private final Comparator<? super String> comparator;
public Set<String> referredVariables;
TraceResolver(Comparator<? super String> comparator) {
this.comparator = comparator;
clear();
}
public void clear() {
referredVariables = new TreeSet<>(comparator);
}
@Override
public String resolve(String name) {
referredVariables.add(name);
return "";
}
}
private static class VariableReferenceSorter extends CyclicGraphDetector<String> {
// map from a variable to a set of variables that variable refers.
private final Map<String, Set<String>> refereeSetMap;
VariableReferenceSorter(Map<String, Set<String>> refereeSetMap) {
this.refereeSetMap = refereeSetMap;
}
@Override
protected Iterable<? extends String> getEdges(String n) {
// return variables referred from the variable.
if (!refereeSetMap.containsKey(n)) {
// there is a case a non-existing variable is referred...
return Collections.emptySet();
}
return refereeSetMap.get(n);
}
}
private final Comparator<? super String> comparator;
private final EnvVars target;
private final Map<String, String> overrides;
private Map<String, Set<String>> refereeSetMap;
private List<String> orderedVariableNames;
OverrideOrderCalculator(EnvVars target, Map<String, String> overrides) {
comparator = target.comparator();
this.target = target;
this.overrides = overrides;
scan();
}
public List<String> getOrderedVariableNames() {
return orderedVariableNames;
}
// Cut the reference to the variable in a cycle.
private void cutCycleAt(String referee, List<String> cycle) {
// cycle contains variables in referrer-to-referee order.
// This should not be negative, for the first and last one is same.
int refererIndex = cycle.lastIndexOf(referee) - 1;
assert refererIndex >= 0;
String referrer = cycle.get(refererIndex);
boolean removed = refereeSetMap.get(referrer).remove(referee);
assert removed;
LOGGER.warning(String.format("Cyclic reference detected: %s", String.join(" -> ", cycle)));
LOGGER.warning(String.format("Cut the reference %s -> %s", referrer, referee));
}
// Cut the variable reference in a cycle.
private void cutCycle(List<String> cycle) {
// if an existing variable is contained in that cycle,
// cut the cycle with that variable:
// existing:
// PATH=/usr/bin
// overriding:
// PATH1=/usr/local/bin:${PATH}
// PATH=/opt/something/bin:${PATH1}
// then consider reference PATH1 -> PATH can be ignored.
for (String referee : cycle) {
if (target.containsKey(referee)) {
cutCycleAt(referee, cycle);
return;
}
}
// if not, cut the reference to the first one.
cutCycleAt(cycle.get(0), cycle);
}
/**
* Scan all variables and list all referring variables.
*/
public void scan() {
refereeSetMap = new TreeMap<>(comparator);
List<String> extendingVariableNames = new ArrayList<>();
TraceResolver resolver = new TraceResolver(comparator);
for (Map.Entry<String, String> entry : overrides.entrySet()) {
if (entry.getKey().indexOf('+') > 0) {
// XYZ+AAA variables should be always processed in last.
extendingVariableNames.add(entry.getKey());
continue;
}
resolver.clear();
Util.replaceMacro(entry.getValue(), resolver);
// Variables directly referred from the current scanning variable.
Set<String> refereeSet = resolver.referredVariables;
// Ignore self reference.
refereeSet.remove(entry.getKey());
refereeSetMap.put(entry.getKey(), refereeSet);
}
VariableReferenceSorter sorter;
while (true) {
sorter = new VariableReferenceSorter(refereeSetMap);
try {
sorter.run(refereeSetMap.keySet());
} catch (CyclicGraphDetector.CycleDetectedException e) {
// cyclic reference found.
// cut the cycle and retry.
@SuppressWarnings("unchecked")
List<String> cycle = e.cycle;
cutCycle(cycle);
continue;
}
break;
}
// When A refers B, the last appearance of B always comes after
// the last appearance of A.
List<String> reversedDuplicatedOrder = new ArrayList<>(sorter.getSorted());
Collections.reverse(reversedDuplicatedOrder);
orderedVariableNames = new ArrayList<>(overrides.size());
for (String key : reversedDuplicatedOrder) {
if (overrides.containsKey(key) && !orderedVariableNames.contains(key)) {
orderedVariableNames.add(key);
}
}
Collections.reverse(orderedVariableNames);
orderedVariableNames.addAll(extendingVariableNames);
}
}
/**
* Overrides all values in the map by the given map. Expressions in values will be expanded.
* See {@link #override(String, String)}.
* @return {@code this}
*/
public EnvVars overrideExpandingAll(Map<String, String> all) {
for (String key : new OverrideOrderCalculator(this, all).getOrderedVariableNames()) {
override(key, expand(all.get(key)));
}
return this;
}
/**
* Resolves environment variables against each other.
*/
public static void resolve(Map<String, String> env) {
for (Map.Entry<String, String> entry : env.entrySet()) {
entry.setValue(Util.replaceMacro(entry.getValue(), env));
}
}
/**
* Convenience message
* @since 1.485
**/
public String get(String key, String defaultValue) {
String v = get(key);
if (v == null) v = defaultValue;
return v;
}
@Override
public String put(String key, String value) {
if (value == null) throw new IllegalArgumentException("Null value not allowed as an environment variable: " + key);
return super.put(key, value);
}
/**
* Add a key/value but only if the value is not-null. Otherwise no-op.
* @since 1.556
*/
public void putIfNotNull(String key, String value) {
if (value != null)
put(key, value);
}
/**
* Add entire map but filter null values out.
* @since 2.214
*/
public void putAllNonNull(Map<String, String> map) {
map.forEach(this::putIfNotNull);
}
/**
* Takes a string that looks like "a=b" and adds that to this map.
*/
public void addLine(String line) {
int sep = line.indexOf('=');
if (sep > 0) {
put(line.substring(0, sep), line.substring(sep + 1));
}
}
/**
* Expands the variables in the given string by using environment variables represented in 'this'.
*/
public String expand(String s) {
return Util.replaceMacro(s, this);
}
/**
* Creates a magic cookie that can be used as the model environment variable
* when we later kill the processes.
*/
public static EnvVars createCookie() {
return new EnvVars("HUDSON_COOKIE", UUID.randomUUID().toString());
}
// /**
// * Obtains the environment variables of a remote peer.
// *
// * @param channel
// * Can be null, in which case the map indicating "N/A" will be returned.
// * @return
// * A fresh copy that can be owned and modified by the caller.
// */
// public static EnvVars getRemote(VirtualChannel channel) throws IOException, InterruptedException {
// if (channel == null)
// return new EnvVars("N/A", "N/A");
// return channel.call(new GetEnvVars());
// }
//
// private static final class GetEnvVars extends MasterToSlaveCallable<EnvVars, RuntimeException> {
// @Override
// public EnvVars call() {
// return new EnvVars(EnvVars.masterEnvVars);
// }
//
// private static final long serialVersionUID = 1L;
// }
//
// /**
// * Environmental variables that we've inherited.
// *
// * <p>
// * Despite what the name might imply, this is the environment variable
// * of the current JVM process. And therefore, it is the Jenkins controller's
// * environment variables only when you access this from the controller.
// *
// * <p>
// * If you access this field from agents, then this is the environment
// * variable of the agent.
// */
// public static final Map<String, String> masterEnvVars = initMaster();
//
// private static EnvVars initMaster() {
// EnvVars vars = new EnvVars(System.getenv());
// vars.platform = Platform.current();
// if (Main.isUnitTest || Main.isDevelopmentMode)
// // if unit test is launched with maven debug switch,
// // we need to prevent forked Maven processes from seeing it, or else
// // they'll hang
// vars.remove("MAVEN_OPTS");
// return vars;
// }
}

View File

@ -0,0 +1,79 @@
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
*
* 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 cd.casic.devops.common.process;
import hudson.util.VersionNumber;
import java.io.File;
import java.util.Locale;
// copy from jenkins 96a66619b55b3b78b86817798fe36e58b2798cd4
/**
* Strategy object that absorbs the platform differences.
*
* <p>
* Do not switch/case on this enum, or do a comparison, as we may add new constants.
*
* @author Kohsuke Kawaguchi
*/
public enum Platform {
WINDOWS(';'), UNIX(':');
/**
* The character that separates paths in environment variables like PATH and CLASSPATH.
* On Windows ';' and on Unix ':'.
*
* @see File#pathSeparator
*/
public final char pathSeparator;
Platform(char pathSeparator) {
this.pathSeparator = pathSeparator;
}
public static Platform current() {
if (File.pathSeparatorChar == ':') return UNIX;
return WINDOWS;
}
public static boolean isDarwin() {
// according to http://developer.apple.com/technotes/tn2002/tn2110.html
return System.getProperty("os.name").toLowerCase(Locale.ENGLISH).startsWith("mac");
}
/**
* Returns true if we run on Mac OS X 10.6
*/
public static boolean isSnowLeopardOrLater() {
try {
return isDarwin() && new VersionNumber(System.getProperty("os.version")).compareTo(new VersionNumber("10.6")) >= 0;
} catch (IllegalArgumentException e) {
// failed to parse the version
return false;
}
}
}

View File

@ -0,0 +1,48 @@
/*
* 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 cd.casic.devops.common.process;
import cd.casic.devops.common.process.BkProcessTree.OSProcess;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public abstract class ProcessKiller implements Serializable {
private static final long serialVersionUID = 1L;
public ProcessKiller() {
}
public static List<ProcessKiller> all() {
return new ArrayList<>();
}
public abstract boolean kill(OSProcess var1) throws IOException, InterruptedException;
}

View File

@ -0,0 +1,54 @@
/*
* 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 cd.casic.devops.common.process;
import java.util.List;
import java.util.Map;
public class ProcessTreeRemoting {
public ProcessTreeRemoting() {
}
public interface IOSProcess {
int getPid();
ProcessTreeRemoting.IOSProcess getParent();
void kill(boolean forceFlag) throws InterruptedException;
void killRecursively(boolean forceFlag) throws InterruptedException;
List<String> getArguments();
EnvVars getEnvironmentVariables();
}
public interface IProcessTree {
void killAll(Map<String, String> var1, boolean forceFlag) throws InterruptedException;
}
}

View File

@ -0,0 +1,557 @@
/*
* (C) Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
*
* Parts of this code was taken from the Jetty project, which can be
* found at http://www.mortbay.org/jetty
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// ========================================================================
// Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package cd.casic.devops.common.process;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
// copy from jenkins 96a66619b55b3b78b86817798fe36e58b2798cd4
/* ------------------------------------------------------------ */
/** StringTokenizer with Quoting support.
*
* This class is a copy of the java.util.StringTokenizer API and
* the behaviour is the same, except that single and double quoted
* string values are recognized.
* Delimiters within quotes are not considered delimiters.
* Quotes can be escaped with '\'.
*
* @see StringTokenizer
* @author Greg Wilkins (gregw)
*/
@SuppressWarnings("all")
public class QuotedStringTokenizer
extends StringTokenizer
{
private static final String __delim = " \t\n\r";
private String _string;
private String _delim = __delim;
private boolean _returnQuotes = false;
private boolean _returnDelimiters = false;
private StringBuilder _token;
private boolean _hasToken = false;
private int _i = 0;
private int _lastStart = 0;
private boolean _double = true;
private boolean _single = true;
public static String[] tokenize(String str) {
return new QuotedStringTokenizer(str).toArray();
}
public static String[] tokenize(String str, String delimiters) {
return new QuotedStringTokenizer(str, delimiters).toArray();
}
/* ------------------------------------------------------------ */
/**
*
* @param str
* String to tokenize.
* @param delim
* List of delimiter characters as string. Can be null, to default to ' \t\n\r'
* @param returnDelimiters
* If true, {@link #nextToken()} will include the delimiters, not just tokenized
* tokens.
* @param returnQuotes
* If true, {@link #nextToken()} will include the quotation characters when they are present.
*/
public QuotedStringTokenizer(String str,
String delim,
boolean returnDelimiters,
boolean returnQuotes)
{
super("");
_string = str;
if (delim != null)
_delim = delim;
_returnDelimiters = returnDelimiters;
_returnQuotes = returnQuotes;
if (_delim.indexOf('\'') >= 0 ||
_delim.indexOf('"') >= 0)
throw new Error("Can't use quotes as delimiters: " + _delim);
_token = new StringBuilder(_string.length() > 1024 ? 512 : _string.length() / 2);
}
/* ------------------------------------------------------------ */
public QuotedStringTokenizer(String str,
String delim,
boolean returnDelimiters)
{
this(str, delim, returnDelimiters, false);
}
/* ------------------------------------------------------------ */
public QuotedStringTokenizer(String str,
String delim)
{
this(str, delim, false, false);
}
/* ------------------------------------------------------------ */
public QuotedStringTokenizer(String str)
{
this(str, null, false, false);
}
public String[] toArray() {
List<String> r = new ArrayList<>();
while (hasMoreTokens())
r.add(nextToken());
return r.toArray(new String[r.size()]);
}
/* ------------------------------------------------------------ */
@Override
public boolean hasMoreTokens()
{
// Already found a token
if (_hasToken)
return true;
_lastStart = _i;
int state = 0;
boolean escape = false;
while (_i < _string.length())
{
char c = _string.charAt(_i++);
switch (state)
{
case 0: // Start
if (_delim.indexOf(c) >= 0)
{
if (_returnDelimiters)
{
_token.append(c);
return _hasToken = true;
}
}
else if (c == '\'' && _single)
{
if (_returnQuotes)
_token.append(c);
state = 2;
}
else if (c == '\"' && _double)
{
if (_returnQuotes)
_token.append(c);
state = 3;
}
else
{
_token.append(c);
_hasToken = true;
state = 1;
}
continue;
case 1: // Token
_hasToken = true;
if (escape)
{
escape = false;
if (ESCAPABLE_CHARS.indexOf(c) < 0)
_token.append('\\');
_token.append(c);
}
else if (_delim.indexOf(c) >= 0)
{
if (_returnDelimiters)
_i--;
return _hasToken;
}
else if (c == '\'' && _single)
{
if (_returnQuotes)
_token.append(c);
state = 2;
}
else if (c == '\"' && _double)
{
if (_returnQuotes)
_token.append(c);
state = 3;
}
else if (c == '\\')
{
escape = true;
}
else
_token.append(c);
continue;
case 2: // Single Quote
_hasToken = true;
if (escape)
{
escape = false;
if (ESCAPABLE_CHARS.indexOf(c) < 0)
_token.append('\\');
_token.append(c);
}
else if (c == '\'')
{
if (_returnQuotes)
_token.append(c);
state = 1;
}
else if (c == '\\')
{
if (_returnQuotes)
_token.append(c);
escape = true;
}
else
_token.append(c);
continue;
case 3: // Double Quote
_hasToken = true;
if (escape)
{
escape = false;
if (ESCAPABLE_CHARS.indexOf(c) < 0)
_token.append('\\');
_token.append(c);
}
else if (c == '\"')
{
if (_returnQuotes)
_token.append(c);
state = 1;
}
else if (c == '\\')
{
if (_returnQuotes)
_token.append(c);
escape = true;
}
else
_token.append(c);
continue;
default:
break;
}
}
return _hasToken;
}
/* ------------------------------------------------------------ */
@Override
public String nextToken()
throws NoSuchElementException
{
if (!hasMoreTokens() || _token == null)
throw new NoSuchElementException();
String t = _token.toString();
_token.setLength(0);
_hasToken = false;
return t;
}
/* ------------------------------------------------------------ */
@Override
public String nextToken(String delim)
throws NoSuchElementException
{
_delim = delim;
_i = _lastStart;
_token.setLength(0);
_hasToken = false;
return nextToken();
}
/* ------------------------------------------------------------ */
@Override
public boolean hasMoreElements()
{
return hasMoreTokens();
}
/* ------------------------------------------------------------ */
@Override
public Object nextElement()
throws NoSuchElementException
{
return nextToken();
}
/* ------------------------------------------------------------ */
/** Not implemented.
*/
@Override
public int countTokens()
{
return -1;
}
/* ------------------------------------------------------------ */
/** Quote a string.
* The string is quoted only if quoting is required due to
* embedded delimiters, quote characters or the
* empty string.
* @param s The string to quote.
* @return quoted string
*/
public static String quote(String s, String delim)
{
if (s == null)
return null;
if (s.isEmpty())
return "\"\"";
for (int i = 0; i < s.length(); i++)
{
char c = s.charAt(i);
if (c == '\\' || c == '"' || c == '\'' || Character.isWhitespace(c) || delim.indexOf(c) >= 0)
{
StringBuffer b = new StringBuffer(s.length() + 8);
quote(b, s);
return b.toString();
}
}
return s;
}
/* ------------------------------------------------------------ */
/** Quote a string.
* The string is quoted only if quoting is required due to
* embedded delimiters, quote characters or the
* empty string.
* @param s The string to quote.
* @return quoted string
*/
public static String quote(String s)
{
if (s == null)
return null;
if (s.isEmpty())
return "\"\"";
StringBuffer b = new StringBuffer(s.length() + 8);
quote(b, s);
return b.toString();
}
/* ------------------------------------------------------------ */
/** Quote a string into a StringBuffer.
* The characters ", \, \n, \r, \t, \f and \b are escaped
* @param buf The StringBuffer
* @param s The String to quote.
*/
public static void quote(StringBuffer buf, String s)
{
synchronized (buf)
{
buf.append('"');
for (int i = 0; i < s.length(); i++)
{
char c = s.charAt(i);
switch (c)
{
case '"':
buf.append("\\\"");
continue;
case '\\':
buf.append("\\\\");
continue;
case '\n':
buf.append("\\n");
continue;
case '\r':
buf.append("\\r");
continue;
case '\t':
buf.append("\\t");
continue;
case '\f':
buf.append("\\f");
continue;
case '\b':
buf.append("\\b");
continue;
default:
buf.append(c);
}
}
buf.append('"');
}
}
/* ------------------------------------------------------------ */
/** Unquote a string.
* @param s The string to unquote.
* @return quoted string
*/
public static String unquote(String s)
{
if (s == null)
return null;
if (s.length() < 2)
return s;
char first = s.charAt(0);
char last = s.charAt(s.length() - 1);
if (first != last || (first != '"' && first != '\''))
return s;
StringBuilder b = new StringBuilder(s.length() - 2);
boolean escape = false;
for (int i = 1; i < s.length() - 1; i++)
{
char c = s.charAt(i);
if (escape)
{
escape = false;
switch (c)
{
case 'n':
b.append('\n');
break;
case 'r':
b.append('\r');
break;
case 't':
b.append('\t');
break;
case 'f':
b.append('\f');
break;
case 'b':
b.append('\b');
break;
case 'u':
b.append((char) (
(convertHexDigit((byte) s.charAt(i++)) << 24) +
(convertHexDigit((byte) s.charAt(i++)) << 16) +
(convertHexDigit((byte) s.charAt(i++)) << 8) +
convertHexDigit((byte) s.charAt(i++))
)
);
break;
default:
b.append(c);
}
}
else if (c == '\\')
{
escape = true;
}
else
b.append(c);
}
return b.toString();
}
/* ------------------------------------------------------------ */
/**
* @return handle double quotes if true
*/
public boolean getDouble()
{
return _double;
}
/* ------------------------------------------------------------ */
/**
* @param d handle double quotes if true
*/
public void setDouble(boolean d)
{
_double = d;
}
/* ------------------------------------------------------------ */
/**
* @return handle single quotes if true
*/
public boolean getSingle()
{
return _single;
}
/* ------------------------------------------------------------ */
/**
* @param single handle single quotes if true
*/
public void setSingle(boolean single)
{
_single = single;
}
/**
* @param b An ASCII encoded character 0-9 a-f A-F
* @return The byte value of the character 0-16.
*/
public static byte convertHexDigit(byte b)
{
if (b >= '0' && b <= '9') return (byte) (b - '0');
if (b >= 'a' && b <= 'f') return (byte) (b - 'a' + 10);
if (b >= 'A' && b <= 'F') return (byte) (b - 'A' + 10);
return 0;
}
/**
* Characters that can be escaped with \.
*
* Others, like, say, \W will be left alone instead of becoming just W.
* This is important to keep Hudson behave on Windows, which uses '\' as
* the directory separator.
*/
private static final String ESCAPABLE_CHARS = "\\\"' ";
}

View File

@ -0,0 +1,101 @@
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
*
* 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 cd.casic.devops.common.process;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// copy from jenkins 96a66619b55b3b78b86817798fe36e58b2798cd4
public class Util {
/**
* Convert null to "".
*/
public static String fixNull(String s) {
return fixNull(s, "");
}
/**
* Convert {@code null} to a default value.
*
* @param defaultValue Default value. It may be immutable or not, depending on the implementation.
* @since 2.144
*/
public static <T> T fixNull(T s, T defaultValue) {
return s != null ? s : defaultValue;
}
/**
* Pattern for capturing variables. Either $xyz, ${xyz} or ${a.b} but not $a.b, while ignoring "$$"
*/
private static final Pattern VARIABLE = Pattern.compile("\\$([A-Za-z0-9_]+|\\{[A-Za-z0-9_.]+\\}|\\$)");
/**
* Replaces the occurrence of '$key' by {@code properties.get('key')}.
*
* <p>
* Unlike shell, undefined variables are left as-is (this behavior is the same as Ant.)
*/
public static String replaceMacro(String s, Map<String, String> properties) {
return replaceMacro(s, new VariableResolver.ByMap<>(properties));
}
/**
* Replaces the occurrence of '$key' by {@code resolver.get('key')}.
*
* <p>
* Unlike shell, undefined variables are left as-is (this behavior is the same as Ant.)
*/
public static String replaceMacro(String s, VariableResolver<String> resolver) {
if (s == null) {
return null;
}
int idx = 0;
while (true) {
Matcher m = VARIABLE.matcher(s);
if (!m.find(idx)) return s;
String key = m.group().substring(1);
// escape the dollar sign or get the key to resolve
String value;
if (key.charAt(0) == '$') {
value = "$";
} else {
if (key.charAt(0) == '{') key = key.substring(1, key.length() - 1);
value = resolver.resolve(key);
}
if (value == null)
idx = m.end(); // skip this
else {
s = s.substring(0, m.start()) + value + s.substring(m.end());
idx = m.start() + value.length();
}
}
}
}

View File

@ -0,0 +1,102 @@
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
*
* 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 cd.casic.devops.common.process;
import java.util.Collection;
import java.util.Map;
// copy from jenkins 96a66619b55b3b78b86817798fe36e58b2798cd4
/**
* Resolves variables to its value, while encapsulating
* how that resolution happens.
*
* @author Kohsuke Kawaguchi
*/
public interface VariableResolver<V> {
/**
* Receives a variable name and obtains the value associated with the name.
*
* <p>
* This can be implemented simply on top of a {@link Map} (see {@link ByMap}), or
* this can be used like an expression evaluator.
*
* @param name
* Name of the variable to be resolved.
* Never null, never empty. The name shouldn't include the syntactic
* marker of an expression. IOW, it should be "foo" but not "${foo}".
* A part of the goal of this design is to abstract away the expression
* marker syntax.
* @return
* Object referenced by the name.
* Null if not found.
*/
V resolve(String name);
/**
* Empty resolver that always returns null.
*/
VariableResolver NONE = name -> null;
/**
* {@link VariableResolver} backed by a {@link Map}.
*/
final class ByMap<V> implements VariableResolver<V> {
private final Map<String, V> data;
public ByMap(Map<String, V> data) {
this.data = data;
}
@Override
public V resolve(String name) {
return data.get(name);
}
}
/**
* Union of multiple {@link VariableResolver}.
*/
final class Union<V> implements VariableResolver<V> {
private final VariableResolver<? extends V>[] resolvers;
public Union(VariableResolver<? extends V>... resolvers) {
this.resolvers = resolvers.clone();
}
public Union(Collection<? extends VariableResolver<? extends V>> resolvers) {
this.resolvers = resolvers.toArray(new VariableResolver[0]);
}
@Override
public V resolve(String name) {
for (VariableResolver<? extends V> r : resolvers) {
V v = r.resolve(name);
if (v != null) return v;
}
return null;
}
}
}

View File

@ -0,0 +1,148 @@
/*
* The MIT License
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi
*
* 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 cd.casic.devops.common.process.jna;
import com.sun.jna.LastErrorException;
import com.sun.jna.Library;
import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;
import com.sun.jna.StringArray;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.NativeLongByReference;
// copy from jenkins 96a66619b55b3b78b86817798fe36e58b2798cd4
/**
* GNU C library.
*
* <p>
* Not available on all platforms (such as Linux/PPC, IBM mainframe, etc.), so the caller should recover gracefully
* in case of {@link LinkageError}. See JENKINS-4820.
* @author Kohsuke Kawaguchi
*/
public interface GNUCLibrary extends Library {
int fork();
int kill(int pid, int signum);
int setsid();
int umask(int mask);
int getpid();
int geteuid();
int getegid();
int getppid();
int chdir(String dir);
int getdtablesize();
int execv(String path, StringArray args);
int execvp(String file, StringArray args);
int setenv(String name, String value, int replace);
int unsetenv(String name);
void perror(String msg);
String strerror(int errno);
int fcntl(int fd, int command);
int fcntl(int fd, int command, Object... flags);
// obtained from Linux. Needs to be checked if these values are portable.
int F_GETFD = 1;
int F_SETFD = 2;
int FD_CLOEXEC = 1;
int chown(String fileName, int uid, int gid);
int chmod(String fileName, int i);
int open(String pathname, int flags) throws LastErrorException;
int dup(int old);
int dup2(int old, int _new);
long pread(int fd, Memory buffer, NativeLong size, NativeLong offset) throws LastErrorException;
int close(int fd);
// see http://www.gnu.org/s/libc/manual/html_node/Renaming-Files.html
int rename(String oldname, String newname);
// The following three functions are Darwin-specific. The native "long" and "size_t" types always have
// the same size on Darwin, we use NativeLong and NativeLongByReference where the native functions use
// "size_t" and "size_t *" respectively. By updating JNA to 5.9.0 and adding a dependency on "jna-platform",
// the "com.sun.jna.platform.unix.LibCAPI.size_t" and "com.sun.jna.platform.unix.LIBCAPI.size_t.ByReference"
// types could be used instead.
// this is listed in http://developer.apple.com/DOCUMENTATION/Darwin/Reference/ManPages/man3/sysctlbyname.3.html
// but not in http://www.gnu.org/software/libc/manual/html_node/System-Parameters.html#index-sysctl-3493
// perhaps it is only supported on BSD?
@Deprecated
int sysctlbyname(String name, Pointer oldp, IntByReference oldlenp, Pointer newp, IntByReference newlen);
int sysctlbyname(String name, Pointer oldp, NativeLongByReference oldlenp, Pointer newp, NativeLong newlen);
@Deprecated
int sysctl(int[] mib, int nameLen, Pointer oldp, IntByReference oldlenp, Pointer newp, IntByReference newlen);
int sysctl(int[] name, int namelen, Pointer oldp, NativeLongByReference oldlenp, Pointer newp, NativeLong newlen);
@Deprecated
int sysctlnametomib(String name, Pointer mibp, IntByReference size);
int sysctlnametomib(String name, Pointer mibp, NativeLongByReference sizep);
/**
* Creates a symlink.
*
* See <a href="https://linux.die.net/man/3/symlink">symlink(3)</a>
*/
int symlink(String oldname, String newname);
/**
* Read a symlink. The name will be copied into the specified memory, and returns the number of
* bytes copied. The string is not null-terminated.
*
* @return
* if the return value equals size, the caller needs to retry with a bigger buffer.
* If -1, error.
*/
int readlink(String filename, Memory buffer, NativeLong size);
GNUCLibrary LIBC = Native.load("c", GNUCLibrary.class);
}

View File

@ -0,0 +1,34 @@
package cd.casic.devops.common.worker;
import java.util.Arrays;
import java.util.List;
public class Constants {
public static final String BUILD_ID = "devops.build.id";
public static final String BUILD_TYPE = "build.type";
public static final String WORKSPACE_ENV = "WORKSPACE";
public static final String COMMON_ENV_CONTEXT = "common_env";
public static final String WORKSPACE_CONTEXT = "ci.workspace";
public static final String CI_TOKEN_CONTEXT = "ci.token";
public static final String JOB_OS_CONTEXT = "job.os";
public static final String SLAVE_AGENT_START_FILE = "devops.slave.agent.start.file";
public static final String SLAVE_AGENT_PREPARE_START_FILE = "devops.slave.agent.prepare.start.file";
public static final String AGENT_ERROR_MSG_FILE = "devops.agent.error.file";
public static final String CLEAN_WORKSPACE = "DEVOPS_CLEAN_WORKSPACE";
public static final String JAVA_PATH_ENV = "bk_java_path";
public static final String NODEJS_PATH_ENV = "bk_nodejs_path";
public static final String LOG_DEBUG_FLAG = "##[debug]";
public static final String LOG_ERROR_FLAG = "##[error]";
public static final String LOG_WARN_FLAG = "##[warning]";
public static final String LOG_SUBTAG_FLAG = "##subTag##";
public static final String LOG_SUBTAG_FINISH_FLAG = "##subTagFinish##";
public static final int LOG_MESSAGE_LENGTH_LIMIT = 16 * 1024; // 16KB
public static final int LOG_TASK_LINE_LIMIT = 1000000;
public static final long LOG_FILE_LENGTH_LIMIT = 1073741824L; // 1 GB = 1073741824 Byte
public static final List<String> PIPELINE_SCRIPT_ATOM_CODE = Arrays.asList(
"PipelineScriptDev",
"PipelineScriptTest",
"PipelineScript"
);
public static final String BK_CI_ATOM_EXECUTE_ENV_PATH = "BK_CI_ATOM_EXECUTE_ENV_PATH";
}

View File

@ -0,0 +1,230 @@
/*
* 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.
*
* ...
*/
package cd.casic.devops.common.worker.constant;
public class WorkerMessageCode {
public static final String MSG_CODE_ROLE_PREFIX = "MSG_CODE_ROLE_PREFIX_";// 角色国际化前缀
public static final String MSG_CODE_PERMISSION_PREFIX = "MSG_CODE_PERMISSION_PREFIX_";// 操作权限国际化前缀
public static final String SUCCESS = "0";// 成功
public static final int OAUTH_DENERD = 418;// 自定义状态码, 未进行oauth认证
public static final String SYSTEM_ERROR = "2100001";// 系统内部繁忙请稍后再试
public static final String PARAMETER_IS_NULL = "2100002";// 参数{0}不能为空
public static final String PARAMETER_IS_EXIST = "2100003";// 参数值{0}已经存在系统请换一个再试
public static final String PARAMETER_IS_INVALID = "2100004";// 参数值{0}为非法数据
public static final String OAUTH_TOKEN_IS_INVALID = "2100005";// 无效的token请先oauth认证
public static final String PERMISSION_DENIED = "2100006";// 无权限{0}
public static final String ERROR_SERVICE_NO_FOUND = "2100007";// "找不到任何有效的{0}服务提供者"
public static final String ERROR_SERVICE_INVOKE_FAILURE = "2100008";// "服务调用失败:{0},uniqueId={1}"
public static final String ERROR_INVALID_CONFIG = "2100009";// "配置不可用:{0},uniqueId={1}"
public static final String ERROR_REST_EXCEPTION_COMMON_TIP = "2100010";// 接口访问出现异常请联系助手或稍后再重试
public static final String ERROR_CLIENT_REST_ERROR = "2100011";// 用户请求不合法参数或方法错误请咨询助手
public static final String ERROR_PROJECT_FEATURE_NOT_ACTIVED = "2100012";// 项目[{0}]未开通该功能
public static final String ERROR_INVALID_PARAM_ = "2100013";// 无效参数: {0}
public static final String ERROR_NEED_PARAM_ = "2100014";// 缺少参数: {0}
public static final String PARAMETER_VALIDATE_ERROR = "2100015";// {0}参数校验错误: {1}
public static final String ERROR_SERVICE_NO_AUTH = "2100016";// 无访问服务的权限
public static final String ERROR_QUERY_NUM_TOO_BIG = "2100017";// 查询的数量超过系统规定的值{0}请调整查询条件或咨询助手
public static final String ERROR_QUERY_TIME_RANGE_TOO_LARGE = "2100018";// 查询的时间范围跨度最大最长时间范围跨度不能超过{0}
public static final String ERROR_HTTP_RESPONSE_BODY_TOO_LARGE = "2100019";// http请求返回体太大
public static final String PERMISSION_DENIED_FOR_APP = "2100020";// APP的无权限{0}
public static final String ERROR_SENSITIVE_API_NO_AUTH = "2100021";// 无敏感API访问权限
public static final String PARAMETER_LENGTH_TOO_LONG = "2100022";// 参数长度不能超过{0}个字符
public static final String PARAMETER_LENGTH_TOO_SHORT = "2100023";// 参数长度不能小于{0}个字符
public static final String PARAMETER_ILLEGAL_ERROR = "2100024";// {0}参数非法错误: {1}
public static final String PARAMETER_EXPIRED_ERROR = "2100025";// {0}token过期错误: {1}
public static final String PARAMETER_SECRET_ERROR = "2100026";// {0}密钥配置错误: {1}
public static final String PARAMETER_IS_EMPTY = "2100027";// 参数不能为空
public static final String ERROR_QUERY_TIME_RANGE_ERROR = "2100028";// 查询的时间范围跨度错误
public static final String SERVICE_NOT_EXIST = "2100029";// 父服务不存在异常
public static final String ILLEGAL_GITCI_SERVICE_IMAGE_FORMAT = "2100030";// GITCI Service镜像格式非法
public static final String THIRD_PARTY_SERVICE_DEVCLOUD_EXCEPTION = "2100031";// 第三方服务-DEVCLOUD 异常请联系8006排查异常信息 -
public static final String CREATE_CONTAINER_INTERFACE_EXCEPTION = "2100032";// 创建容器接口异常
public static final String CREATE_CONTAINER_RETURNS_FAILED = "2100033";// 创建容器接口返回失败
public static final String CREATE_CONTAINER_TIMED_OUT = "2100034";// 创建容器接口超时
public static final String OPERATION_CONTAINER_INTERFACE_EXCEPTION = "2100035";// 操作容器接口异常
public static final String OPERATION_CONTAINER_RETURNED_FAILURE = "2100036";// 操作容器接口返回失败
public static final String OPERATION_CONTAINER_TIMED_OUT = "2100037";// 操作容器接口超时
public static final String GET_STATUS_INTERFACE_EXCEPTION = "2100038";// 获取容器状态接口异常
public static final String GET_STATUS_TIMED_OUT = "2100039";// 获取容器状态接口超时
public static final String CREATE_MIRROR_INTERFACE_EXCEPTION = "2100040";// 创建镜像接口异常
public static final String CREATE_MIRROR_INTERFACE_RETURNED_FAILURE = "2100041";// 创建镜像接口返回失败
public static final String CREATE_MIRROR_INTERFACE_EXCEPTION_NEW = "2100042";// 创建镜像新版本接口异常
public static final String NEW_MIRROR_INTERFACE_RETURNED_FAILURE = "2100043";// 创建镜像新版本接口返回失败
public static final String TASK_STATUS_INTERFACE_EXCEPTION = "2100044";// 获取TASK状态接口异常
public static final String TASK_STATUS_TIMED_OUT = "2100045";// 获取TASK状态接口超时
public static final String GET_WEBSOCKET_INTERFACE_EXCEPTION = "2100046";// 获取websocket接口异常
public static final String PARAMETER_CANNOT_EMPTY_ALL = "2100047";// 参数不能全部为空
public static final String USERS_EXCEEDS_THE_LIMIT = "2100048";// 授权用户数越界:{0}
public static final String FAILED_TO_QUERY_GSE_AGENT_STATUS = "2100049";// 查询 Gse Agent 状态失败
public static final String FAILED_TO_GET_AGENT_STATUS = "2100050";// 获取agent状态失败
public static final String STAGES_AND_STEPS_CANNOT_EXIST_BY_SIDE = "2100053";// stages和steps不能并列存在!
public static final String USER_NOT_PERMISSIONS_OPERATE_PIPELINE = "2100054";// 用户({0})无权限在工程({1}){2}流水线{3}
public static final String USER_NOT_HAVE_PROJECT_PERMISSIONS = "2100055";// 用户 {0}无项目{1}权限
public static final String UNABLE_GET_PIPELINE_JOB_STATUS = "2100056";// 无法获取流水线JOB状态构建停止
public static final String JOB_BUILD_STOPS = "2100057";// 流水线JOB已经不再运行构建停止
public static final String PIPELINE_NAME_OCCUPIED = "2100058";// 流水线名称已被他人使用
public static final String INTERNAL_DEPENDENCY_SERVICE_EXCEPTION = "2100059";// 内部依赖服务异常
public static final String PUBLIC_BUILD_RESOURCE_POOL_NOT_EXIST = "2100060";// 公共构建资源池不存在请检查yml配置.
public static final String ERROR_LANGUAGE_IS_NOT_SUPPORT = "2100061";// 该语言蓝盾目前不支持蓝盾目前支持的语言标识为{0}
public static final String INIT_SERVICE_LIST_ERROR = "2100062";// 初始化服务列表异常问题
public static final String FILE_NOT_EXIST = "2100063";// 文件{0}不存在
public static final String USER_ACCESS_CHECK_FAIL = "2100064";// Gitlab access token 不正确
public static final String GITLAB_TOKEN_EMPTY = "2100065";// GitLab Token为空
public static final String GITLAB_HOOK_URL_EMPTY = "2100066";// GitLab hook url为空
public static final String GITLAB_TOKEN_FAIL = "2100067";// GitLab Token不正确
public static final String GIT_TOKEN_FAIL = "2100068";// Git Token不正确
public static final String SERCRT_EMPTY = "2100069";// GIT 私钥为空
public static final String GIT_SERCRT_WRONG = "2100070";// Git 私钥不对
public static final String PWD_EMPTY = "2100071";// 用户密码为空
public static final String USER_NAME_EMPTY = "2100072";// 用户名为空
public static final String GITLAB_INVALID = "2100073";// 无效的GITLAB仓库
public static final String GIT_TOKEN_WRONG = "2100074";// Git Token 不正确
public static final String GIT_LOGIN_FAIL = "2100075";// Git 用户名或者密码不对
public static final String GIT_TOKEN_EMPTY = "2100076";// Git Token为空
public static final String GIT_HOOK_URL_EMPTY = "2100077";// Git hook url为空
public static final String TGIT_LOGIN_FAIL = "2100078";// TGit 用户名或者密码不对
public static final String TGIT_TOKEN_FAIL = "2100079";// TGit Token 不正确
public static final String TGIT_SECRET_WRONG = "2100080";// TGit 私钥不对
public static final String SVN_SECRET_OR_PATH_ERROR = "2100081";// SVN 私钥不正确 或者 SVN 路径没有权限
public static final String SVN_CREATE_HOOK_FAIL = "2100082";// 添加SVN WEB hook 失败
public static final String LOCK_FAIL = "2100083";// lock失败
public static final String UNLOCK_FAIL = "2100084";// unlock失败
public static final String GIT_REPO_PEM_FAIL = "2100085";// 代码仓库访问未授权
public static final String CALL_REPO_ERROR = "2100086";// 代码仓库访问异常
public static final String P4_USERNAME_PASSWORD_FAIL = "2100087";// p4用户名密码错误
public static final String PARAM_ERROR = "2100088";// 参数错误
public static final String AUTH_FAIL = "2100089";// {0}认证失败
public static final String ACCOUNT_NO_OPERATION_PERMISSIONS = "2100090";// 账户没有{0}的权限
public static final String REPO_NOT_EXIST_OR_NO_OPERATION_PERMISSION = "2100091";// {0}仓库不存在或者是账户没有该项目{1}的权限
public static final String GIT_INTERFACE_NOT_EXIST = "2100092";// {0}平台没有{1}的接口
public static final String GIT_CANNOT_OPERATION = "2100093";// {0}平台{1}操作不能进行
public static final String WEBHOOK_LOCK_UNLOCK_FAIL = "2100094";// unlock webhooklock失败,请确认token是否已经配置
public static final String COMMIT_CHECK_ADD_FAIL = "2100095";// Commit Check添加失败请确保该代码库的凭据关联的用户对代码库有Developer权限
public static final String ADD_MR_COMMENTS_FAIL = "2100096";// 添加MR的评论失败请确保该代码库的凭据关联的用户对代码库有Developer权限
public static final String WEBHOOK_ADD_FAIL = "2100097";// Webhook添加失败请确保该代码库的凭据关联的用户对代码库有{0}权限
public static final String WEBHOOK_UPDATE_FAIL = "2100098";// Webhook更新失败请确保该代码库的凭据关联的用户对代码库有Developer权限
public static final String ENGINEERING_REPO_UNAUTHORIZED = "2100099";// 工程仓库访问未授权
public static final String ENGINEERING_REPO_NOT_EXIST = "2100100";// 工程仓库不存在
public static final String ENGINEERING_REPO_CALL_ERROR = "2100101";// 工程仓库访问异常
public static final String NOT_MEMBER_AND_NOT_OPEN_SOURCE = "2100102";// 非项目成员且项目为非开源项目
public static final String USER_NO_PIPELINE_PERMISSION = "2100108";// 流水线: 用户无{0}权限
public static final String SERVICE_COULD_NOT_BE_ANALYZED = "2100109";// 无法根据接口"{0}"分析所属的服务
public static final String RETURNED_RESULT_COULD_NOT_BE_PARSED = "2100110";// 内部服务返回结果无法解析 status:{0} body:{1}
public static final String SERVICE_PROVIDER_NOT_FOUND = "2100111";// 找不到任何有效的{0}{1}服务提供者
public static final String ILLEGAL_JOB_TYPE = "2100112";// 非法的job类型!
public static final String ERROR_YAML_FORMAT_EXCEPTION = "2100113";// {0} {1} 格式有误,应为 {2}, error message:{3}
public static final String ERROR_YAML_FORMAT_EXCEPTION_CHECK_STAGE_LABEL = "2100114";// 请核对Stage标签是否正确
public static final String ERROR_YAML_FORMAT_EXCEPTION_LENGTH_LIMIT_EXCEEDED = "2100115";// "{0} job.id 超过长度限制64 {1}}"
public static final String ERROR_YAML_FORMAT_EXCEPTION_NEED_PARAM = "2100116";// {0} 中的step必须包含uses或run或checkout!
public static final String ERROR_YAML_FORMAT_EXCEPTION_SERVICE_IMAGE_FORMAT_ILLEGAL = "2100117";// STREAM Service镜像格式非法
public static final String ERROR_YAML_FORMAT_EXCEPTION_STEP_ID_UNIQUENESS = "2100118";// 请确保step.id唯一性!({0})
public static final String BUILD_RESOURCE_NOT_EXIST = "2100119";// {0}构建资源不存在请检查yml配置.
public static final String ERROR_YAML_FORMAT_EXCEPTION_ENV_QUANTITY_LIMIT_EXCEEDED = "2100120";// {0}配置Env数量超过100限制!
;// {0}Env单变量{1}长度超过{2}字符!({3})
public static final String ERROR_YAML_FORMAT_EXCEPTION_ENV_VARIABLE_LENGTH_LIMIT_EXCEEDED = "2100121";
public static final String ERROR_PROJECT_API_ACCESS_NO_PERMISSION = "2100122";// 项目[{0}]没有接口[{1}]的访问权限
public static final String ERROR_INTERFACE_RETRY_NUM_EXCEEDED = "2100123";// 接口连续重试次数超过{0}请稍后再试
public static final String ERROR_PIPELINE_API_ACCESS_NO_PERMISSION = "2100124";// 流水线[{0}]没有接口[{1}]的访问权限
public static final String TEMPLATE_PLUGIN_NOT_ALLOWED_USE = "2100125";// 模板中插件{0}{1}版本的状态是{2}不允许使用
public static final String ADD_MR_FAIL = "2100126";// 添加MR失败
;// 互转使用
public static final String ELEMENT_UPDATE_WRONG_PATH = "2100127";// 更新插件的标注位置有误
public static final String ELEMENT_NOT_SUPPORT_TRANSFER = "2100128";// 如下插件在 Code 方式下已不支持请修改后再切换: \n[{0}]
public static final String DISPATCH_NOT_SUPPORT_TRANSFER = "2100129";// 如下构建环境在 Code 方式下不支持转换请修改后再切换: \n[{0}]
public static final String YAML_NOT_VALID = "2100130";// yaml不合法 {0}
public static final String GIT_INVALID_PRIVATE_KEY = "2100131";// 不支持的SSH私钥格式仅支持rsa格式私钥
public static final String GIT_INVALID_PRIVATE_KEY_OR_PASSWORD = "2100132";// 第三方服务[{0}]操作失败失败详情{1}
public static final String MR_ACCEPT_EVENT_NOT_SUPPORT_TRANSFER = "2100133";// mr accept事件类型不支持code转换
public static final String SVN_TOKEN_FAIL = "2100135";// SVN Token 不正确
public static final String SVN_TOKEN_EMPTY = "2100136";// SVN Token 为空, 请检查代码库的凭证类型
public static final String BK_CONTAINER_TIMED_OUT = "bkContainerTimedOut";// 创建容器超时
public static final String BK_CREATION_FAILED_EXCEPTION_INFORMATION = "bkCreationFailedExceptionInformation";// 创建失败异常信息
public static final String BK_FILE_NAME = "bkFileName";// 文件名
public static final String BK_BELONG_TO_THE_PROJECT = "bkBelongToTheProject";// 所属项目
public static final String BK_OPERATING = "bkOperating";// 操作
public static final String BK_PUSH_FROM_BLUE_SHIELD_DEVOPS_PLATFORM = "bkPushFromBlueShieldDevopsPlatform";// 来自蓝盾DevOps平台的推送
public static final String BK_TABLE_CONTENTS = "bkTableContents";// 表格内容
public static final String BK_PLEASE_FEEL_TO_CONTACT_BLUE_SHIELD_ASSISTANT = "bkPleaseFeelToContactBlueShieldAssistant";// 如有任何问题可随时联系蓝盾助手
public static final String BK_ETH1_NETWORK_CARD_IP_EMPTY = "bkEth1NetworkCardIpEmpty";// eth1 网卡Ip为空因此获取eth0的网卡ip
public static final String BK_LOOPBACK_ADDRESS_OR_NIC_EMPTY = "bkLoopbackAddressOrNicEmpty";// loopback地址或网卡名称为空
public static final String BK_FAILED_GET_NETWORK_CARD = "bkFailedGetNetworkCard";// 获取网卡失败
public static final String BK_MANUAL_TRIGGER = "bkManualTrigger";// 手动触发
public static final String BK_BUILD_TRIGGER = "bkBuildTrigger";// 构建触发
public static final String BK_VIEW_DETAILS = "bkSeeDetails";// 查看详情
public static final String BK_PROJECT_ID = "bkProjectId";// # 项目ID:
public static final String BK_PIPELINE_NAME = "bkPipelineName";// # 流水线名称:
public static final String BK_CREATE_SERVICE = "bkCreateService";// 创建{0}服务
public static final String BK_SESSION_ID = "bkSessionId";// 会话ID
public static final String BK_GROUP_ID = "bkGroupId";// 群ID
public static final String BK_THIS_GROUP_ID = "bkThisGroupId";// 本群ID={0}PS:群ID可用于蓝盾平台上任意企业微信群通知
public static final String BK_MISSING_RESOURCE_DEPENDENCY = "bkMissingResourceDependency";// 依赖的资源不存在
public static final String BK_REQUEST_TIMED_OUT = "bkRequestTimedOut";// 请求超时
public static final String BK_QUERY_PARAM_REQUEST_ERROR = "bkQueryParamRequestError";// 查询参数请求错误
public static final String BK_JSON_BAD_PARAMETERS = "bkJsonBadParameters";// JSON参数错误/Bad Parameters in json
;// 请求体内容参数错误温馨提示请确认{0}是否符合要求
public static final String BK_REQUEST_BODY_CONTENT_PARAMETER_INCORRECT = "bkRequestBodyContentParameterIncorrect";
public static final String BK_REQUESTED_RESOURCE_DOES_NOT_EXIST = "bkRequestedResourceDoesNotExist";// 请求的资源不存在
public static final String BK_NOT_OAUTH_CERTIFICATION = "bkNotOauthCertification";// 你没有Oauth认证
public static final String BK_QUERY_PARAM_REQUEST_EMPTY = "bkQueryParamRequestEmpty";// 请求的参数内容为空
public static final String BK_QUERY_PARAM_TYPE_ERROR = "bkQueryParamTypeError";// 查询参数类型错误
;// 你没有权限进行该操作
public static final String BK_NOT_HAVE_PERMISSION_PERFORM_THIS_OPERATION = "bkNotHavePermissionPerformThisOperation";// 访问后台数据失败已通知产品开发请稍后重试
public static final String BK_FAILED_ACCESS_BACKGROUND_DATA = "bkFailedAccessBackgroundData";// 未授权访问的资源
public static final String BK_RESOURCES_THAT_NOT_AUTHORIZED_ACCESS = "bkResourcesThatNotAuthorizedAccess";
public static final String BK_CODE_BASE_TRIGGERING = "bkCodeBaseTriggering";// 代码库触发
public static final String BK_FAILED_START_BUILD_MACHINE = "bkFailedStartBuildMachine";// 启动构建机失败
public static final String CREATE_BRANCH = "bkCreateBranch";// 创建分支
public static final String DELETE_BRANCH = "bkDeleteBranch";// 删除分支
public static final String GET_PROJECT_INFO = "bkGetProjectInfo";// 获取项目详情
public static final String GET_COMMIT_REVIEW_INFO = "bkGetCommitReviewInfo";// 获取Commit Review详情
public static final String GET_SESSION_INFO = "bkGetSessionInfo";// 获取会话详情
public static final String OPERATION_BRANCH = "bkOperationBranch";// 拉分支
public static final String OPERATION_TAG = "bkOperationTag";// 拉标签
public static final String OPERATION_ADD_WEBHOOK = "bkOperationAddWebhook";// 添加WEBHOOK
public static final String OPERATION_UPDATE_WEBHOOK = "bkOperationUpdateWebhook";// 修改WEBHOOK
public static final String OPERATION_LIST_WEBHOOK = "bkOperationListWebhook";// 查询WEBHOOK
public static final String OPERATION_ADD_COMMIT_CHECK = "bkOperationAddCommitCheck";// 添加COMMIT CHECK
public static final String OPERATION_ADD_MR_COMMENT = "bkOperationAddMrComment";// 添加MR COMMENT
public static final String OPERATION_LIST_MR = "bkOperationListMr";// 添加MR
public static final String OPERATION_ADD_MR = "bkOperationAddMr";// 添加MR
public static final String OPERATION_COMMIT = "bkOperationCommit";// 拉提交记录
public static final String OPERATION_COMMIT_DIFF = "bkOperationCommitDiff";// 查询commit变化
public static final String OPERATION_UNLOCK_HOOK_LOCK = "bkOperationUnlockHookLock";// 解锁hook锁
public static final String OPERATION_MR_CHANGE = "bkOperationMrChange";// 查询合并请求的代码变更
public static final String OPERATION_MR_INFO = "bkOperationMrInfo";// 查询项目合并请求
public static final String OPERATION_GET_CHANGE_FILE_LIST = "bkOperationGetChangeFileList";// 查询变更文件列表
public static final String OPERATION_GET_MR_COMMIT_LIST = "bkOperationGetMrCommitList";// 获取合并请求中的提交
public static final String OPERATION_PROJECT_USER_INFO = "bkOperationProjectUserInfo";// 获取项目中成员信息
public static final String OPERATION_TAPD_WORKITEMS = "bkOperationTapdWorkItems";// 查看绑定的TAPD单
public static final String BK_USER_GROUP_CRATE_TIME = "bkUserGroupCrateTime";// {0} 用户组:{1},{2} 创建于
public static final String BK_USER_RATING_ADMIN_CRATE_TIME = "bkUserRatingAdminCrateTime";// {0} 分级管理员,{1} 创建于
public static final String BK_SECOND_LEVEL_ADMIN_CREATE = "bkSecondLevelAdminCreate";// {0} 二级管理员, {1} 创建于
public static final String BK_SECOND_LEVEL_ADMIN_REVISE = "bkSecondLevelAdminRevise";// {0} 二级管理员, {1} 修改于
;// 用户 {0} 申请{1}蓝盾项目 {2} ,请审批
public static final String BK_USER_REQUESTS_THE_PROJECT = "bkUserRequestsTheProject";
public static final String BK_ENV_NOT_YET_SUPPORTED = "bkEnvNotYetSupported";// 尚未支持 {0} {1}请联系 管理员 添加对应版本
public static final String BK_BUILD_ENV_TYPE = "BUILD_ENV_TYPE_";// 构建环境-
public static final String BK_BUILD_ENV_TYPE_BUILDLESS = "BUILD_ENV_TYPE_BUILDLESS";// 无编译环境
public static final String BK_BUILD_ENV_TYPE_BUILD_TRIGGERS = "BUILD_ENV_TYPE_BUILD_TRIGGER";// 构建触发
}

View File

@ -0,0 +1,186 @@
/*
* 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.
*
* ...
*/
package cd.casic.devops.common.worker.env;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.awt.OSInfo;
import java.io.File;
import java.io.FileInputStream;
import java.util.Locale;
import java.util.Properties;
public class AgentEnv {
private static final Logger logger = LoggerFactory.getLogger(AgentEnv.class);
public static final String PROJECT_ID = "devops.project.id";
public static final String DOCKER_PROJECT_ID = "devops_project_id";
public static final String AGENT_ID = "devops.agent.id";
public static final String DOCKER_AGENT_ID = "devops_agent_id";
public static final String AGENT_SECRET_KEY = "devops.agent.secret.key";
public static final String DOCKER_AGENT_SECRET_KEY = "devops_agent_secret_key";
public static final String AGENT_GATEWAY = "landun.gateway";
public static final String DOCKER_GATEWAY = "devops_gateway";
public static final String AGENT_FILE_GATEWAY = "DEVOPS_FILE_GATEWAY";
public static final String AGENT_ENV = "landun.env";
public static final String AGENT_LOG_SAVE_MODE = "devops_log_save_mode";
public static final String AGENT_PROPERTIES_FILE_NAME = ".agent.properties";
public static final String BK_TAG = "devops_bk_tag";
public static final String PUBLIC_HOST_MAX_FILE_CACHE_SIZE = "devops.public.host.maxFileCacheSize";
public static final String THIRD_HOST_MAX_FILE_CACHE_SIZE = "devops.public.third.maxFileCacheSize";
private static String projectId;
private static String agentId;
private static String secretKey;
private static String gateway;
private static String fileGateway;
private static OSInfo.OSType os;
// private static Env env;
// private static LogStorageMode logStorageMode;
private static String bkTag;
private static Properties property;
private static final File propertyFile = new File(System.getProperty("user.home"), AGENT_PROPERTIES_FILE_NAME);
public static String getProjectId() {
if (projectId == null) {
synchronized (AgentEnv.class) {
if (projectId == null) {
projectId = getProperty(PROJECT_ID);
logger.info("Get the project ID({})", projectId);
}
}
}
return projectId;
}
public static String getAgentId() {
if (agentId == null) {
synchronized (AgentEnv.class) {
if (agentId == null) {
agentId = getProperty(AGENT_ID);
logger.info("Get the agent ID({})", agentId);
}
}
}
return agentId;
}
public static String getSecretKey() {
if (secretKey == null) {
synchronized (AgentEnv.class) {
if (secretKey == null) {
secretKey = getProperty(AGENT_SECRET_KEY);
logger.info("Get the secret key({})", secretKey);
}
}
}
return secretKey;
}
public static String getGateway() {
if (gateway == null) {
synchronized (AgentEnv.class) {
if (gateway == null) {
gateway = getProperty(AGENT_GATEWAY);
logger.info("Get the gateway({})", gateway);
}
}
}
return gateway;
}
public static String getFileGateway() {
if (fileGateway == null) {
synchronized (AgentEnv.class) {
if (fileGateway == null) {
fileGateway = getProperty(AGENT_FILE_GATEWAY);
logger.info("Get the file gateway({})", fileGateway);
}
}
}
return fileGateway;
}
public static OSInfo.OSType getOs() {
if (os == null) {
synchronized (AgentEnv.class) {
if (os == null) {
os = OSInfo.OSType.valueOf(System.getProperty("os.name").toUpperCase(Locale.ROOT));
logger.info("Get the OS type({})", os);
}
}
}
return os;
}
/* public static LogStorageMode getLogMode() {
if (logStorageMode == null) {
synchronized (AgentEnv.class) {
if (logStorageMode == null) {
logStorageMode = LogStorageMode.valueOf(getProperty(AGENT_LOG_SAVE_MODE));
logger.info("Get the log mode({})", logStorageMode);
}
}
}
return logStorageMode;
}*/
public static String getBkTag() {
if (bkTag == null) {
synchronized (AgentEnv.class) {
if (bkTag == null) {
bkTag = getProperty(BK_TAG);
logger.info("Get the bkTag({})", bkTag);
}
}
}
return bkTag;
}
@SneakyThrows
public static String getProperty(String prop) {
if (property == null) {
if (!propertyFile.exists()) {
throw new Exception("The property file(" + propertyFile.getAbsolutePath() + ") does not exist");
// throw new ParamBlankException("The property file(" + propertyFile.getAbsolutePath() + ") does not exist");
}
property = new Properties();
try (FileInputStream fis = new FileInputStream(propertyFile)) {
property.load(fis);
} catch (Exception e) {
logger.error("Failed to load properties from file", e);
}
}
return property.getProperty(prop);
}
public static String getEnvProp(String prop) {
String value = System.getenv(prop);
if (value == null || value.isEmpty()) {
value = System.getProperty(prop);
}
return value;
}
public static boolean isDockerEnv() {
return BuildEnv.getBuildType() == BuildType.DOCKER;
}
public static String getLocaleLanguage() {
return null;
// return System.getProperty(LOCALE_LANGUAGE, System.getenv(LOCALE_LANGUAGE) != null ? System.getenv(LOCALE_LANGUAGE) : DEFAULT_LOCALE_LANGUAGE);
}
}

View File

@ -0,0 +1,51 @@
/*
* 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.
*
* ...
*/
package cd.casic.devops.common.worker.env;
import static cd.casic.devops.common.worker.Constants.BUILD_ID;
import static cd.casic.devops.common.worker.Constants.BUILD_TYPE;
public class BuildEnv {
private static String buildType;
public static BuildType getBuildType() {
if (buildType == null) {
synchronized (BuildEnv.class) {
if (buildType == null) {
buildType = System.getProperty(BUILD_TYPE);
}
}
}
if (buildType == null || !BuildType.contains(buildType)) {
return BuildType.AGENT;
}
return BuildType.valueOf(buildType);
}
public static void setBuildType(BuildType value) {
buildType = value.name();
}
public static boolean isThirdParty() {
return getBuildType() == BuildType.AGENT;
}
public static String getBuildId() {
return System.getProperty(BUILD_ID);
}
public static void setBuildId(String buildId) {
System.setProperty(BUILD_ID, buildId);
}
}

View File

@ -0,0 +1,30 @@
/*
* 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.
*
* ...
*/
package cd.casic.devops.common.worker.env;
public enum BuildType {
WORKER,
AGENT,
MACOS,
MACOS_NEW,
DOCKER;
public static boolean contains(String env) {
for (BuildType type : values()) {
if (type.name().equals(env)) {
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,198 @@
/*
* 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.
*
* ...
*/
package cd.casic.devops.common.worker.env;
import com.tencent.devops.worker.common.exception.PropertyNotExistException;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DockerEnv {
private static final Logger logger = LoggerFactory.getLogger(DockerEnv.class);
private static final String PROJECT_ID = "devops_project_id";
private static final String BUILD_ID = "devops_build_id";
private static final String AGENT_ID = "devops_agent_id";
private static final String AGENT_SECRET_KEY = "devops_agent_secret_key";
private static final String AGENT_GATEWAY = "devops_gateway";
private static final String JOB_POOL = "JOB_POOL";
private static final String DOCKER_HOST_IP = "docker_host_ip";
private static final String DOCKER_HOST_PORT = "docker_host_port";
private static final String HOSTNAME = "HOSTNAME";
private static String projectId;
private static String buildId;
private static String agentId;
private static String secretKey;
private static String gateway;
private static String jobPool;
private static String dockerHostIp;
private static String dockerHostPort;
private static String hostname;
public static void setProjectId(String projectId) {
System.setProperty(PROJECT_ID, projectId);
}
@SneakyThrows
public static String getProjectId() {
if (projectId == null) {
synchronized (DockerEnv.class) {
if (projectId == null) {
projectId = getProperty(PROJECT_ID);
if (projectId == null || projectId.isEmpty()) {
throw new Exception(PROJECT_ID+ "Empty project Id");
// throw new PropertyNotExistException(PROJECT_ID, "Empty project Id");
}
logger.info("Get the project ID({})", projectId);
}
}
}
return projectId;
}
public static void setBuildId(String buildId) {
System.setProperty(BUILD_ID, buildId);
}
@SneakyThrows
public static String getBuildId() {
if (buildId == null) {
synchronized (DockerEnv.class) {
if (buildId == null) {
buildId = getProperty(BUILD_ID);
if (buildId == null || buildId.isEmpty()) {
throw new Exception(BUILD_ID+ "Empty build Id");
// throw new PropertyNotExistException(BUILD_ID, "Empty build Id");
}
logger.info("Get the build ID({})", buildId);
}
}
}
return buildId;
}
public static String getAgentId() {
if (agentId == null) {
synchronized (DockerEnv.class) {
if (agentId == null) {
agentId = getProperty(AGENT_ID);
if (agentId == null || agentId.isEmpty()) {
throw new PropertyNotExistException(AGENT_ID, "Empty agent Id");
}
logger.info("Get the agent ID({})", agentId);
}
}
}
return agentId;
}
public static void setAgentSecretKey(String secretKey) {
System.setProperty(AGENT_SECRET_KEY, secretKey);
}
public static String getAgentSecretKey() {
if (secretKey == null) {
synchronized (DockerEnv.class) {
if (secretKey == null) {
secretKey = getProperty(AGENT_SECRET_KEY);
if (secretKey == null || secretKey.isEmpty()) {
throw new PropertyNotExistException(AGENT_SECRET_KEY, "Empty agent secret key");
}
logger.info("Get the agent secret key({})", secretKey);
}
}
}
return secretKey;
}
public static String getGateway() {
if (gateway == null) {
synchronized (DockerEnv.class) {
if (gateway == null) {
gateway = getProperty(AGENT_GATEWAY);
if (gateway == null || gateway.isEmpty()) {
throw new PropertyNotExistException(AGENT_GATEWAY, "Empty agent gateway");
}
logger.info("Get the gateway({})", gateway);
}
}
}
return gateway;
}
public static String getJobPool() {
if (jobPool == null) {
synchronized (DockerEnv.class) {
if (jobPool == null) {
jobPool = getProperty(JOB_POOL);
logger.info("Get the jobPool({})", jobPool);
}
}
}
return jobPool;
}
public static String getDockerHostIp() {
if (dockerHostIp == null) {
synchronized (DockerEnv.class) {
if (dockerHostIp == null) {
dockerHostIp = getProperty(DOCKER_HOST_IP);
if (dockerHostIp == null || dockerHostIp.isEmpty()) {
throw new PropertyNotExistException(DOCKER_HOST_IP, "Empty dockerHostIp");
}
logger.info("Get the dockerHostIp({})", dockerHostIp);
}
}
}
return dockerHostIp;
}
public static String getDockerHostPort() {
if (dockerHostPort == null) {
synchronized (DockerEnv.class) {
if (dockerHostPort == null) {
dockerHostPort = getProperty(DOCKER_HOST_PORT);
if (dockerHostPort == null || dockerHostPort.isEmpty()) {
throw new PropertyNotExistException(DOCKER_HOST_PORT, "Empty dockerHostPort");
}
logger.info("Get the dockerHostPort({})", dockerHostPort);
}
}
}
return dockerHostPort;
}
public static String getHostname() {
if (hostname == null) {
synchronized (DockerEnv.class) {
if (hostname == null) {
hostname = getProperty(HOSTNAME);
if (hostname == null || hostname.isEmpty()) {
throw new PropertyNotExistException(HOSTNAME, "Empty hostname");
}
logger.info("Get the hostname({})", hostname);
}
}
}
return hostname;
}
private static String getProperty(String prop) {
String value = System.getenv(prop);
if (value == null || value.isEmpty()) {
value = System.getProperty(prop);
}
return value;
}
}

View File

@ -0,0 +1,154 @@
//package com.tencent.devops.worker.common.exception
//
//import com.fasterxml.jackson.databind.exc.InvalidFormatException
//import com.fasterxml.jackson.databind.exc.MismatchedInputException
//import com.tencent.devops.common.api.exception.RemoteServiceException
//import com.tencent.devops.common.api.exception.TaskExecuteException
//import com.tencent.devops.common.api.pojo.ErrorCode
//import com.tencent.devops.common.api.pojo.ErrorType
//import com.tencent.devops.worker.common.exception.TaskExecuteExceptionDecorator.LOGGER
//import org.slf4j.Logger
//import org.slf4j.LoggerFactory
//import java.io.FileNotFoundException
//import java.io.IOException
//
///**
// * 错误处理
// */
//object TaskExecuteExceptionDecorator {
//
// val LOGGER: Logger = LoggerFactory.getLogger(TaskExecuteExceptionDecorator::class.java)
//
// private val defaultExceptionBase = DefaultExceptionBase()
//
// private val factory = mutableMapOf(
// IllegalStateException::class to IllegalStateExceptionD(),
// InvalidFormatException::class to InvalidFormatExceptionD(),
// FileNotFoundException::class to FileNotFoundExceptionD(),
// RemoteServiceException::class to RemoteServiceExceptionD(),
// MismatchedInputException::class to MismatchedInputExceptionD(),
// IOException::class to IOExceptionD(),
// FileSystemException::class to FileSystemExceptionD()
// )
//
// @Suppress("UNCHECKED_CAST")
// fun decorate(throwable: Throwable): TaskExecuteException {
// var exception = throwable
// return (factory[exception::class] as ExceptionDecorator<Throwable>? ?: exception.cause?.let { cause ->
// (factory[cause::class] as ExceptionDecorator<Throwable>?)?.let {
// exception = cause
// it
// }
// } ?: defaultExceptionBase).decorate(exception)
// }
//}
//
//class DefaultExceptionBase : ExceptionDecorator<Throwable> {
// override fun decorate(exception: Throwable): TaskExecuteException {
// return when {
// exception is TaskExecuteException -> exception
// // TEE只有一层所以不遍历cause防止InputMismatchException 无限循环。
// exception.cause is TaskExecuteException -> exception.cause as TaskExecuteException
// else -> {
// LOGGER.warn("[Worker Error]: ", exception)
// val defaultMessage = StringBuilder("Unknown system error has occurred with StackTrace:\n")
// defaultMessage.append(exception.toString())
// exception.stackTrace.forEach {
// with(it) {
// defaultMessage.append(
// "\n at $className.$methodName($fileName:$lineNumber)"
// )
// }
// }
// TaskExecuteException(
// errorMsg = exception.message ?: defaultMessage.toString(),
// errorType = ErrorType.SYSTEM,
// errorCode = ErrorCode.SYSTEM_WORKER_LOADING_ERROR,
// cause = exception
// )
// }
// }
// }
//}
//
//interface ExceptionDecorator<T : Throwable> {
// fun decorate(exception: T): TaskExecuteException
//}
//
//class IllegalStateExceptionD : ExceptionDecorator<IllegalStateException> {
// override fun decorate(exception: IllegalStateException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "Machine process error: ${exception.message}",
// errorType = ErrorType.USER,
// errorCode = ErrorCode.THIRD_PARTY_BUILD_ENV_ERROR,
// cause = exception
// )
// }
//}
//
//class FileNotFoundExceptionD : ExceptionDecorator<FileNotFoundException> {
// override fun decorate(exception: FileNotFoundException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "Machine file not found error: ${exception.message}",
// errorType = ErrorType.USER,
// errorCode = ErrorCode.USER_RESOURCE_NOT_FOUND,
// cause = exception
// )
// }
//}
//
//class RemoteServiceExceptionD : ExceptionDecorator<RemoteServiceException> {
//
// override fun decorate(exception: RemoteServiceException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "THIRD PARTY response error: ${exception.message}",
// errorType = ErrorType.THIRD_PARTY,
// errorCode = ErrorCode.THIRD_PARTY_INTERFACE_ERROR,
// cause = exception
// )
// }
//}
//
//class MismatchedInputExceptionD : ExceptionDecorator<MismatchedInputException> {
// override fun decorate(exception: MismatchedInputException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "Plugin data is illegal: ${exception.message}",
// errorType = ErrorType.PLUGIN,
// errorCode = ErrorCode.USER_TASK_OPERATE_FAIL,
// cause = exception
// )
// }
//}
//
//class InvalidFormatExceptionD : ExceptionDecorator<InvalidFormatException> {
// override fun decorate(exception: InvalidFormatException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "Plugin data is illegal: ${exception.message}",
// errorType = ErrorType.PLUGIN,
// errorCode = ErrorCode.USER_TASK_OPERATE_FAIL,
// cause = exception
// )
// }
//}
//
//class IOExceptionD : ExceptionDecorator<IOException> {
// override fun decorate(exception: IOException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "IO Exception: ${exception.message}",
// errorType = ErrorType.USER,
// errorCode = ErrorCode.USER_RESOURCE_NOT_FOUND,
// cause = exception
// )
// }
//}
//
//class FileSystemExceptionD : ExceptionDecorator<FileSystemException> {
// override fun decorate(exception: FileSystemException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "FileSystem Exception: ${exception.message}",
// errorType = ErrorType.USER,
// errorCode = ErrorCode.USER_RESOURCE_NOT_FOUND,
// cause = exception
// )
// }
//}

View File

@ -0,0 +1,30 @@
/*
* 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 com.tencent.devops.worker.common.exception
class ApiNotExistException(message: String) : RuntimeException(message)

View File

@ -0,0 +1,30 @@
/*
* 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 com.tencent.devops.worker.common.exception
class PropertyNotExistException(val key: String, message: String) : RuntimeException(message)

View File

@ -0,0 +1,154 @@
//package com.tencent.devops.worker.common.exception
//
//import com.fasterxml.jackson.databind.exc.InvalidFormatException
//import com.fasterxml.jackson.databind.exc.MismatchedInputException
//import com.tencent.devops.common.api.exception.RemoteServiceException
//import com.tencent.devops.common.api.exception.TaskExecuteException
//import com.tencent.devops.common.api.pojo.ErrorCode
//import com.tencent.devops.common.api.pojo.ErrorType
//import com.tencent.devops.worker.common.exception.TaskExecuteExceptionDecorator.LOGGER
//import org.slf4j.Logger
//import org.slf4j.LoggerFactory
//import java.io.FileNotFoundException
//import java.io.IOException
//
///**
// * 错误处理
// */
//object TaskExecuteExceptionDecorator {
//
// val LOGGER: Logger = LoggerFactory.getLogger(TaskExecuteExceptionDecorator::class.java)
//
// private val defaultExceptionBase = DefaultExceptionBase()
//
// private val factory = mutableMapOf(
// IllegalStateException::class to IllegalStateExceptionD(),
// InvalidFormatException::class to InvalidFormatExceptionD(),
// FileNotFoundException::class to FileNotFoundExceptionD(),
// RemoteServiceException::class to RemoteServiceExceptionD(),
// MismatchedInputException::class to MismatchedInputExceptionD(),
// IOException::class to IOExceptionD(),
// FileSystemException::class to FileSystemExceptionD()
// )
//
// @Suppress("UNCHECKED_CAST")
// fun decorate(throwable: Throwable): TaskExecuteException {
// var exception = throwable
// return (factory[exception::class] as ExceptionDecorator<Throwable>? ?: exception.cause?.let { cause ->
// (factory[cause::class] as ExceptionDecorator<Throwable>?)?.let {
// exception = cause
// it
// }
// } ?: defaultExceptionBase).decorate(exception)
// }
//}
//
//class DefaultExceptionBase : ExceptionDecorator<Throwable> {
// override fun decorate(exception: Throwable): TaskExecuteException {
// return when {
// exception is TaskExecuteException -> exception
// // TEE只有一层所以不遍历cause防止InputMismatchException 无限循环。
// exception.cause is TaskExecuteException -> exception.cause as TaskExecuteException
// else -> {
// LOGGER.warn("[Worker Error]: ", exception)
// val defaultMessage = StringBuilder("Unknown system error has occurred with StackTrace:\n")
// defaultMessage.append(exception.toString())
// exception.stackTrace.forEach {
// with(it) {
// defaultMessage.append(
// "\n at $className.$methodName($fileName:$lineNumber)"
// )
// }
// }
// TaskExecuteException(
// errorMsg = exception.message ?: defaultMessage.toString(),
// errorType = ErrorType.SYSTEM,
// errorCode = ErrorCode.SYSTEM_WORKER_LOADING_ERROR,
// cause = exception
// )
// }
// }
// }
//}
//
//interface ExceptionDecorator<T : Throwable> {
// fun decorate(exception: T): TaskExecuteException
//}
//
//class IllegalStateExceptionD : ExceptionDecorator<IllegalStateException> {
// override fun decorate(exception: IllegalStateException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "Machine process error: ${exception.message}",
// errorType = ErrorType.USER,
// errorCode = ErrorCode.THIRD_PARTY_BUILD_ENV_ERROR,
// cause = exception
// )
// }
//}
//
//class FileNotFoundExceptionD : ExceptionDecorator<FileNotFoundException> {
// override fun decorate(exception: FileNotFoundException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "Machine file not found error: ${exception.message}",
// errorType = ErrorType.USER,
// errorCode = ErrorCode.USER_RESOURCE_NOT_FOUND,
// cause = exception
// )
// }
//}
//
//class RemoteServiceExceptionD : ExceptionDecorator<RemoteServiceException> {
//
// override fun decorate(exception: RemoteServiceException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "THIRD PARTY response error: ${exception.message}",
// errorType = ErrorType.THIRD_PARTY,
// errorCode = ErrorCode.THIRD_PARTY_INTERFACE_ERROR,
// cause = exception
// )
// }
//}
//
//class MismatchedInputExceptionD : ExceptionDecorator<MismatchedInputException> {
// override fun decorate(exception: MismatchedInputException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "Plugin data is illegal: ${exception.message}",
// errorType = ErrorType.PLUGIN,
// errorCode = ErrorCode.USER_TASK_OPERATE_FAIL,
// cause = exception
// )
// }
//}
//
//class InvalidFormatExceptionD : ExceptionDecorator<InvalidFormatException> {
// override fun decorate(exception: InvalidFormatException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "Plugin data is illegal: ${exception.message}",
// errorType = ErrorType.PLUGIN,
// errorCode = ErrorCode.USER_TASK_OPERATE_FAIL,
// cause = exception
// )
// }
//}
//
//class IOExceptionD : ExceptionDecorator<IOException> {
// override fun decorate(exception: IOException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "IO Exception: ${exception.message}",
// errorType = ErrorType.USER,
// errorCode = ErrorCode.USER_RESOURCE_NOT_FOUND,
// cause = exception
// )
// }
//}
//
//class FileSystemExceptionD : ExceptionDecorator<FileSystemException> {
// override fun decorate(exception: FileSystemException): TaskExecuteException {
// return TaskExecuteException(
// errorMsg = "FileSystem Exception: ${exception.message}",
// errorType = ErrorType.USER,
// errorCode = ErrorCode.USER_RESOURCE_NOT_FOUND,
// cause = exception
// )
// }
//}

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<configuration scan="false" debug="false">
<property name="pattern"
value="[%date{dd MMM yyyy;HH:mm:ss.SSS}][%thread] %-5level %logger{36}:%method:%line - %msg%n"/>
<contextName>logback</contextName>
<!--输出到文件-->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH:-.}/logs/${AGENT_LOG_PREFIX:-agent}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH:-.}/logs/${AGENT_LOG_PREFIX:-agent}-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>14</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!--本地备份log-->
<appender name="runtime" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH:-.}/logs/runtime.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH:-.}/logs/runtime-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>10GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${pattern}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<logger name="com.tencent.devops.worker.common.api.log.LogResourceApi" level="INFO" additivity="false">
<appender-ref ref="runtime" />
</logger>
<root level="INFO">
<appender-ref ref="file"/>
</root>
</configuration>

View File

@ -0,0 +1,6 @@
{
"dev": {
"baseUrl": "127.0.0.1:48080",
"adminTenentId": "1"
}
}