Skip to content

Commit 3eddfae

Browse files
author
李浩
committed
[IMP] 拉取gitops仓库失败时,尝试刷新deploy-key
1 parent f1ab1c9 commit 3eddfae

13 files changed

+93
-53
lines changed

src/main/java/io/choerodon/devops/app/service/impl/AppServiceInstanceServiceImpl.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
import io.kubernetes.client.models.V1Service;
2222
import io.kubernetes.client.models.V1beta1Ingress;
2323
import org.apache.commons.lang.StringUtils;
24-
import org.hzero.core.base.BaseConstants;
25-
import org.hzero.core.util.Pair;
2624
import org.slf4j.Logger;
2725
import org.slf4j.LoggerFactory;
2826
import org.springframework.beans.BeanUtils;
@@ -84,6 +82,9 @@
8482
import io.choerodon.mybatis.pagehelper.PageHelper;
8583
import io.choerodon.mybatis.pagehelper.domain.PageRequest;
8684

85+
import org.hzero.core.base.BaseConstants;
86+
import org.hzero.core.util.Pair;
87+
8788

8889
/**
8990
* Created by Zenger on 2018/4/12.
@@ -311,7 +312,7 @@ public Page<AppServiceInstanceInfoVO> pageInstanceInfoByOptions(Long projectId,
311312
Map<String, Object> maps = TypeUtil.castMapParams(params);
312313
List<Long> updatedEnv = clusterConnectionHandler.getUpdatedClusterList();
313314
Page<AppServiceInstanceInfoVO> pageInfo = ConvertUtils.convertPage(PageHelper.doPageAndSort(PageRequestUtil.getMappedPage(pageable, orderByFieldMap), () -> appServiceInstanceMapper.listInstanceInfoByEnvAndOptions(
314-
envId, TypeUtil.cast(maps.get(TypeUtil.SEARCH_PARAM)), TypeUtil.cast(maps.get(TypeUtil.PARAMS)))),
315+
envId, TypeUtil.cast(maps.get(TypeUtil.SEARCH_PARAM)), TypeUtil.cast(maps.get(TypeUtil.PARAMS)))),
315316
AppServiceInstanceInfoVO.class);
316317
Set<Long> marketInstanceCommandVersionIds = new HashSet<>();
317318
Set<Long> appServiceIds = new HashSet<>();
@@ -1179,6 +1180,7 @@ public void createInstanceBySaga(InstanceSagaPayload instanceSagaPayload) {
11791180
String filePath = null;
11801181
if (instanceSagaPayload.getAppServiceDeployVO().getType().equals(UPDATE)) {
11811182
filePath = clusterConnectionHandler.handDevopsEnvGitRepository(
1183+
instanceSagaPayload.getDevopsEnvironmentDTO(),
11821184
instanceSagaPayload.getProjectId(),
11831185
instanceSagaPayload.getDevopsEnvironmentDTO().getCode(),
11841186
instanceSagaPayload.getDevopsEnvironmentDTO().getId(),
@@ -1253,6 +1255,7 @@ public void createMarketInstanceBySaga(MarketInstanceSagaPayload instanceSagaPay
12531255
String filePath = null;
12541256
if (instanceSagaPayload.getMarketInstanceCreationRequestVO().getCommandType().equals(UPDATE)) {
12551257
filePath = clusterConnectionHandler.handDevopsEnvGitRepository(
1258+
instanceSagaPayload.getDevopsEnvironmentDTO(),
12561259
instanceSagaPayload.getProjectId(),
12571260
instanceSagaPayload.getDevopsEnvironmentDTO().getCode(),
12581261
instanceSagaPayload.getDevopsEnvironmentDTO().getId(),
@@ -1690,6 +1693,7 @@ public void deleteInstance(Long projectId, Long instanceId, Boolean deletePromet
16901693

16911694
//判断当前容器目录下是否存在环境对应的gitops文件目录,不存在则克隆
16921695
String path = clusterConnectionHandler.handDevopsEnvGitRepository(
1696+
devopsEnvironmentDTO,
16931697
devopsEnvironmentDTO.getProjectId(),
16941698
devopsEnvironmentDTO.getCode(),
16951699
devopsEnvironmentDTO.getId(),

src/main/java/io/choerodon/devops/app/service/impl/CertificationServiceImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ private void operateEnvGitLabFile(String certName,
297297
C7nCertification c7nCertification) {
298298
UserAttrDTO userAttrDTO = userAttrService.baseQueryById(TypeUtil.objToLong(GitUserNameUtil.getUserId()));
299299
gitlabGroupMemberService.checkEnvProject(devopsEnvironmentDTO, userAttrDTO);
300-
clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), EnvironmentType.USER.getValue(), devopsEnvironmentDTO.getClusterCode());
300+
clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO, devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), EnvironmentType.USER.getValue(), devopsEnvironmentDTO.getClusterCode());
301301

302302
ResourceConvertToYamlHandler<C7nCertification> resourceConvertToYamlHandler = new ResourceConvertToYamlHandler<>();
303303
resourceConvertToYamlHandler.setType(c7nCertification);
@@ -376,6 +376,7 @@ public void deleteById(Long projectId, Long certId) {
376376
null, gitLabEnvProjectId,
377377
"delete", userAttrDTO.getGitlabUserId(), certId, certificateType, null, false, certEnvId,
378378
clusterConnectionHandler.handDevopsEnvGitRepository(
379+
devopsEnvironmentDTO,
379380
devopsEnvironmentDTO.getProjectId(),
380381
devopsEnvironmentDTO.getCode(),
381382
devopsEnvironmentDTO.getId(),

src/main/java/io/choerodon/devops/app/service/impl/DevopsConfigMapServiceImpl.java

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,19 @@
22

33
import static io.choerodon.devops.infra.constant.MiscConstants.*;
44

5+
import java.util.ArrayList;
6+
import java.util.List;
7+
import java.util.Map;
8+
59
import com.google.gson.Gson;
610
import com.google.gson.reflect.TypeToken;
11+
import io.kubernetes.client.models.V1ConfigMap;
12+
import io.kubernetes.client.models.V1ObjectMeta;
13+
import org.springframework.beans.factory.annotation.Autowired;
14+
import org.springframework.context.annotation.Lazy;
15+
import org.springframework.stereotype.Service;
16+
import org.springframework.transaction.annotation.Transactional;
17+
718
import io.choerodon.core.domain.Page;
819
import io.choerodon.core.exception.CommonException;
920
import io.choerodon.devops.api.vo.DevopsConfigMapRespVO;
@@ -23,16 +34,6 @@
2334
import io.choerodon.devops.infra.util.*;
2435
import io.choerodon.mybatis.pagehelper.PageHelper;
2536
import io.choerodon.mybatis.pagehelper.domain.PageRequest;
26-
import io.kubernetes.client.models.V1ConfigMap;
27-
import io.kubernetes.client.models.V1ObjectMeta;
28-
import org.springframework.beans.factory.annotation.Autowired;
29-
import org.springframework.context.annotation.Lazy;
30-
import org.springframework.stereotype.Service;
31-
import org.springframework.transaction.annotation.Transactional;
32-
33-
import java.util.ArrayList;
34-
import java.util.List;
35-
import java.util.Map;
3637

3738
@Service
3839
public class DevopsConfigMapServiceImpl implements DevopsConfigMapService {
@@ -105,7 +106,7 @@ public void createOrUpdate(Long projectId, Boolean sync, DevopsConfigMapVO devop
105106
}
106107
DevopsEnvCommandDTO devopsEnvCommandDTO = initDevopsEnvCommandDTO(devopsConfigMapVO.getType());
107108
//判断当前容器目录下是否存在环境对应的gitops文件目录,不存在则克隆
108-
String filePath = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
109+
String filePath = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO, devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
109110
//在gitops库处理ingress文件
110111
operateEnvGitLabFile(
111112
TypeUtil.objToInteger(devopsEnvironmentDTO.getGitlabEnvProjectId()), v1ConfigMap, devopsConfigMapVO.getType().equals(CREATE_TYPE), filePath, devopsConfigMapDTO, userAttrDTO, devopsEnvCommandDTO, devopsConfigMapVO.getAppServiceId());
@@ -212,7 +213,7 @@ public void delete(Long projectId, Long configMapId) {
212213

213214

214215
//判断当前容器目录下是否存在环境对应的gitops文件目录,不存在则克隆
215-
String path = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
216+
String path = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO, devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
216217

217218
//查询改对象所在文件中是否含有其它对象
218219
DevopsEnvFileResourceDTO devopsEnvFileResourceDTO = devopsEnvFileResourceService

src/main/java/io/choerodon/devops/app/service/impl/DevopsCustomizeResourceServiceImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ public void createOrUpdateResource(Long projectId, DevopsCustomizeResourceCreate
154154
} else {
155155
//判断当前容器目录下是否存在环境对应的gitops文件目录,不存在则克隆
156156
String gitOpsPath = clusterConnectionHandler.handDevopsEnvGitRepository(
157+
devopsEnvironmentDTO,
157158
devopsEnvironmentDTO.getProjectId(),
158159
devopsEnvironmentDTO.getCode(),
159160
devopsEnvironmentDTO.getId(),
@@ -212,6 +213,7 @@ public void deleteResource(Long projectId, Long resourceId) {
212213

213214
//判断当前容器目录下是否存在环境对应的gitops文件目录,不存在则克隆
214215
String gitOpsPath = clusterConnectionHandler.handDevopsEnvGitRepository(
216+
devopsEnvironmentDTO,
215217
devopsEnvironmentDTO.getProjectId(),
216218
devopsEnvironmentDTO.getCode(),
217219
devopsEnvironmentDTO.getId(),

src/main/java/io/choerodon/devops/app/service/impl/DevopsGitServiceImpl.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,7 @@ public void fileResourceSync(PushWebHookVO pushWebHookVO) {
723723

724724
try {
725725
//更新本地库到最新提交
726-
Git git = handDevopsEnvGitRepository(path, url, devopsEnvironmentDTO.getEnvIdRsa());
726+
Git git = handDevopsEnvGitRepository(devopsEnvironmentDTO, path, url, devopsEnvironmentDTO.getEnvIdRsa());
727727
LOGGER.info("更新gitops库成功");
728728
//查询devops-sync tag是否存在,存在则比较tag和最新commit的diff,不存在则识别gitops库下所有文件为新增文件
729729
tagNotExist = getDevopsSyncTag(pushWebHookVO);
@@ -1190,10 +1190,10 @@ private boolean getDevopsSyncTag(PushWebHookVO pushWebHookVO) {
11901190

11911191
}
11921192

1193-
private Git handDevopsEnvGitRepository(String path, String url, String envIdRsa) {
1193+
private Git handDevopsEnvGitRepository(DevopsEnvironmentDTO devopsEnvironmentDTO, String path, String url, String envIdRsa) {
11941194
File file = new File(path);
11951195
if (!file.exists()) {
1196-
return gitUtil.cloneBySsh(path, url, envIdRsa);
1196+
return gitUtil.cloneBySsh(devopsEnvironmentDTO, path, url, envIdRsa);
11971197
} else {
11981198
if (file.isDirectory() && file.listFiles().length > 0) {
11991199
try {
@@ -1204,13 +1204,13 @@ private Git handDevopsEnvGitRepository(String path, String url, String envIdRsa)
12041204
if (e instanceof CheckoutConflictException) {
12051205
// 删除本地gitops文件,然后重新clone
12061206
FileUtil.deleteDirectory(file);
1207-
return gitUtil.cloneBySsh(path, url, envIdRsa);
1207+
return gitUtil.cloneBySsh(devopsEnvironmentDTO, path, url, envIdRsa);
12081208
} else {
12091209
throw new CommonException("error.git.pull", e);
12101210
}
12111211
}
12121212
} else {
1213-
return gitUtil.cloneBySsh(path, url, envIdRsa);
1213+
return gitUtil.cloneBySsh(devopsEnvironmentDTO, path, url, envIdRsa);
12141214
}
12151215
}
12161216
}

src/main/java/io/choerodon/devops/app/service/impl/DevopsIngressServiceImpl.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ public void updateIngress(Long id, DevopsIngressVO devopsIngressVO, Long project
309309

310310

311311
// 判断当前容器目录下是否存在环境对应的gitops文件目录,不存在则克隆
312-
String path = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
312+
String path = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO, devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
313313

314314
//在gitops库处理ingress文件
315315
operateEnvGitLabFile(
@@ -462,7 +462,7 @@ public void deleteIngress(Long projectId, Long ingressId) {
462462

463463

464464
// 判断当前容器目录下是否存在环境对应的gitops文件目录,不存在则克隆
465-
String path = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
465+
String path = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO, devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
466466

467467
// 查询改对象所在文件中是否含有其它对象
468468
DevopsEnvFileResourceDTO devopsEnvFileResourceDTO = devopsEnvFileResourceService
@@ -650,6 +650,7 @@ public void operateIngressBySaga(IngressSagaPayload ingressSagaPayload) {
650650
String filePath = null;
651651
if (!ingressSagaPayload.getCreated()) {
652652
filePath = clusterConnectionHandler.handDevopsEnvGitRepository(
653+
ingressSagaPayload.getDevopsEnvironmentDTO(),
653654
ingressSagaPayload.getProjectId(),
654655
ingressSagaPayload.getDevopsEnvironmentDTO().getCode(),
655656
ingressSagaPayload.getDevopsEnvironmentDTO().getId(),

src/main/java/io/choerodon/devops/app/service/impl/DevopsPvServiceImpl.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ public Boolean deletePvById(Long projectId, Long pvId) {
207207

208208
// 判断当前容器目录下是否存在环境对应的gitops文件目录,不存在则克隆
209209
String path = clusterConnectionHandler.handDevopsEnvGitRepository(
210+
devopsEnvironmentDTO,
210211
devopsEnvironmentDTO.getProjectId(),
211212
devopsEnvironmentDTO.getCode(),
212213
devopsEnvironmentDTO.getId(),
@@ -725,7 +726,9 @@ private void operatePVGitlabFile(Integer gitlabEnvGroupProjectId, V1PersistentVo
725726
public void operatePvBySaga(PersistentVolumePayload persistentVolumePayload) {
726727
try {
727728
// 判断当前容器目录下是否存在环境对应的gitops文件目录,不存在则克隆
728-
String path = clusterConnectionHandler.handDevopsEnvGitRepository(persistentVolumePayload.getDevopsEnvironmentDTO().getProjectId(),
729+
String path = clusterConnectionHandler.handDevopsEnvGitRepository(
730+
persistentVolumePayload.getDevopsEnvironmentDTO(),
731+
persistentVolumePayload.getDevopsEnvironmentDTO().getProjectId(),
729732
persistentVolumePayload.getDevopsEnvironmentDTO().getCode(),
730733
persistentVolumePayload.getDevopsEnvironmentDTO().getId(),
731734
persistentVolumePayload.getDevopsEnvironmentDTO().getEnvIdRsa(),
@@ -769,13 +772,13 @@ public List<DevopsPvLabelVO> listLabels(Long projectId, Long clusterId) {
769772
.filter(s -> !StringUtils.isEmpty(s))
770773
.map(s -> JsonHelper.unmarshalByJackson(s, new TypeReference<Map<String, String>>() {
771774
}))
772-
.forEach(l -> l.forEach((k, v)->{
775+
.forEach(l -> l.forEach((k, v) -> {
773776
DevopsPvLabelVO devopsPvLabelVO = new DevopsPvLabelVO();
774777
devopsPvLabelVO.setKey(k);
775778
devopsPvLabelVO.setValue(v);
776-
if (!labels.contains(devopsPvLabelVO)){
777-
labels.add(devopsPvLabelVO);
778-
}
779+
if (!labels.contains(devopsPvLabelVO)) {
780+
labels.add(devopsPvLabelVO);
781+
}
779782
}));
780783
return labels;
781784
}

src/main/java/io/choerodon/devops/app/service/impl/DevopsPvcServiceImpl.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ public boolean delete(Long projectId, Long envId, Long pvcId) {
138138
baseUpdate(devopsPvcDTO);
139139

140140
//判断当前容器目录下是否存在环境对应的gitops文件目录,不存在则克隆
141-
String path = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
141+
String path = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO, devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
142142

143143
// 查询对象所在文件中是否含有其它对象
144144
DevopsEnvFileResourceDTO devopsEnvFileResourceDTO = devopsEnvFileResourceService
@@ -392,7 +392,9 @@ private void operateEnvGitLabFile(Integer gitlabEnvGroupProjectId, V1PersistentV
392392
public void operatePvcBySaga(PersistentVolumeClaimPayload persistentVolumeClaimPayload) {
393393
try {
394394
// 判断当前容器目录下是否存在环境对应的gitops文件目录,不存在则克隆
395-
String path = clusterConnectionHandler.handDevopsEnvGitRepository(persistentVolumeClaimPayload.getProjectId(),
395+
String path = clusterConnectionHandler.handDevopsEnvGitRepository(
396+
persistentVolumeClaimPayload.getDevopsEnvironmentDTO(),
397+
persistentVolumeClaimPayload.getProjectId(),
396398
persistentVolumeClaimPayload.getDevopsEnvironmentDTO().getCode(),
397399
persistentVolumeClaimPayload.getDevopsEnvironmentDTO().getId(),
398400
persistentVolumeClaimPayload.getDevopsEnvironmentDTO().getEnvIdRsa(),

src/main/java/io/choerodon/devops/app/service/impl/DevopsSecretServiceImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ private void operateEnvGitLabFile(Integer gitlabEnvGroupProjectId, V1Secret v1Se
255255
}
256256

257257
// 判断当前容器目录下是否存在环境对应的gitops文件目录,不存在则克隆
258-
String path = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
258+
String path = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO, devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
259259

260260
ResourceConvertToYamlHandler<V1Secret> resourceConvertToYamlHandler = new ResourceConvertToYamlHandler<>();
261261
resourceConvertToYamlHandler.setType(v1Secret);
@@ -288,7 +288,7 @@ public Boolean deleteSecret(Long projectId, Long envId, Long secretId) {
288288
baseUpdate(devopsSecretDTO);
289289

290290
//判断当前容器目录下是否存在环境对应的gitops文件目录,不存在则克隆
291-
String path = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
291+
String path = clusterConnectionHandler.handDevopsEnvGitRepository(devopsEnvironmentDTO, devopsEnvironmentDTO.getProjectId(), devopsEnvironmentDTO.getCode(), devopsEnvironmentDTO.getId(), devopsEnvironmentDTO.getEnvIdRsa(), devopsEnvironmentDTO.getType(), devopsEnvironmentDTO.getClusterCode());
292292

293293
// 查询该对象所在文件中是否含有其它对象
294294
DevopsEnvFileResourceDTO devopsEnvFileResourceDTO = devopsEnvFileResourceService

0 commit comments

Comments
 (0)