6
6
package org .eclipse .xpanse .tofu .maker .opentofu .service ;
7
7
8
8
import java .io .File ;
9
+ import java .io .IOException ;
10
+ import java .nio .file .Files ;
11
+ import java .nio .file .Path ;
12
+ import java .nio .file .Paths ;
13
+ import java .util .Comparator ;
9
14
import java .util .HashMap ;
15
+ import java .util .List ;
10
16
import java .util .Objects ;
11
17
import java .util .UUID ;
12
18
import lombok .extern .slf4j .Slf4j ;
19
+ import org .apache .commons .lang3 .StringUtils ;
13
20
import org .eclipse .jgit .api .CloneCommand ;
14
21
import org .eclipse .jgit .api .errors .GitAPIException ;
22
+ import org .eclipse .jgit .storage .file .FileRepositoryBuilder ;
15
23
import org .eclipse .xpanse .tofu .maker .async .TaskConfiguration ;
16
24
import org .eclipse .xpanse .tofu .maker .models .exceptions .GitRepoCloneException ;
17
25
import org .eclipse .xpanse .tofu .maker .models .exceptions .OpenTofuExecutorException ;
36
44
@ Component
37
45
public class OpenTofuGitRepoService extends OpenTofuDirectoryService {
38
46
47
+ private static final int MAX_RETRY_COUNT = 5 ;
39
48
private final RestTemplate restTemplate ;
40
49
private final OpenTofuExecutor executor ;
41
50
private final OpenTofuScriptsHelper openTofuScriptsHelper ;
@@ -66,7 +75,8 @@ public OpenTofuValidationResult validateWithScripts(
66
75
* Method to get openTofu plan.
67
76
*/
68
77
public OpenTofuPlan getOpenTofuPlanFromGitRepo (OpenTofuPlanFromGitRepoRequest request ,
69
- UUID uuid ) {
78
+ UUID uuid ) {
79
+ uuid = getUuidToCreateEmptyWorkspace (uuid );
70
80
buildDeployEnv (request .getGitRepoDetails (), uuid );
71
81
return getOpenTofuPlanFromDirectory (request ,
72
82
getScriptsLocationInRepo (request .getGitRepoDetails (), uuid ));
@@ -76,6 +86,7 @@ public OpenTofuPlan getOpenTofuPlanFromGitRepo(OpenTofuPlanFromGitRepoRequest re
76
86
* Method of deployment a service using a script.
77
87
*/
78
88
public OpenTofuResult deployFromGitRepo (OpenTofuDeployFromGitRepoRequest request , UUID uuid ) {
89
+ uuid = getUuidToCreateEmptyWorkspace (uuid );
79
90
buildDeployEnv (request .getGitRepoDetails (), uuid );
80
91
return deployFromDirectory (request , getScriptsLocationInRepo (
81
92
request .getGitRepoDetails (), uuid ));
@@ -86,6 +97,7 @@ public OpenTofuResult deployFromGitRepo(OpenTofuDeployFromGitRepoRequest request
86
97
*/
87
98
public OpenTofuResult destroyFromGitRepo (OpenTofuDestroyFromGitRepoRequest request ,
88
99
UUID uuid ) {
100
+ uuid = getUuidToCreateEmptyWorkspace (uuid );
89
101
buildDestroyEnv (request .getGitRepoDetails (), request .getTfState (), uuid );
90
102
return destroyFromDirectory (request , getScriptsLocationInRepo (
91
103
request .getGitRepoDetails (), uuid ));
@@ -125,6 +137,7 @@ public void asyncDestroyFromGitRepo(OpenTofuAsyncDestroyFromGitRepoRequest reque
125
137
result = destroyFromGitRepo (request , uuid );
126
138
} catch (RuntimeException e ) {
127
139
result = OpenTofuResult .builder ()
140
+ .destroyScenario (request .getDestroyScenario ())
128
141
.commandStdOutput (null )
129
142
.commandStdError (e .getMessage ())
130
143
.isCommandSuccessful (false )
@@ -145,6 +158,25 @@ private void buildDeployEnv(OpenTofuScriptGitRepoDetails openTofuScriptGitRepoDe
145
158
extractScripts (workspace , openTofuScriptGitRepoDetails );
146
159
}
147
160
161
+ private void buildDestroyEnv (OpenTofuScriptGitRepoDetails openTofuScriptGitRepoDetails ,
162
+ String tfState , UUID uuid ) {
163
+ buildDeployEnv (openTofuScriptGitRepoDetails , uuid );
164
+ openTofuScriptsHelper .createTfStateFile (tfState ,
165
+ uuid + File .separator + openTofuScriptGitRepoDetails .getScriptPath ());
166
+ }
167
+
168
+ private UUID getUuidToCreateEmptyWorkspace (UUID uuid ) {
169
+ File ws = new File (executor .getModuleFullPath (uuid .toString ()));
170
+ if (ws .exists ()) {
171
+ if (!cleanWorkspace (uuid )) {
172
+ uuid = UUID .randomUUID ();
173
+ log .info ("Clean existed workspace failed. Create empty workspace with id:{}" , uuid );
174
+ return UUID .randomUUID ();
175
+ }
176
+ }
177
+ return uuid ;
178
+ }
179
+
148
180
private void buildWorkspace (String workspace ) {
149
181
log .info ("start create workspace" );
150
182
File ws = new File (workspace );
@@ -156,36 +188,64 @@ private void buildWorkspace(String workspace) {
156
188
}
157
189
158
190
private void extractScripts (String workspace ,
159
- OpenTofuScriptGitRepoDetails openTofuScriptGitRepoDetails ) {
160
- log .info ("Cloning GIT repo" );
161
- try {
191
+ OpenTofuScriptGitRepoDetails scriptsRepo ) {
192
+ log .info ("Cloning scripts from GIT repo:{} to workspace:{}" , scriptsRepo .getRepoUrl (),
193
+ workspace );
194
+ File workspaceDirectory = new File (workspace );
195
+ FileRepositoryBuilder repositoryBuilder = new FileRepositoryBuilder ();
196
+ repositoryBuilder .findGitDir (workspaceDirectory );
197
+ if (Objects .isNull (repositoryBuilder .getGitDir ())) {
162
198
CloneCommand cloneCommand = new CloneCommand ();
163
- cloneCommand .setURI (openTofuScriptGitRepoDetails .getRepoUrl ());
199
+ cloneCommand .setURI (scriptsRepo .getRepoUrl ());
164
200
cloneCommand .setProgressMonitor (null );
165
- cloneCommand .setDirectory (new File (workspace ));
166
- cloneCommand .setBranch (openTofuScriptGitRepoDetails .getBranch ());
167
- cloneCommand .call ();
168
- } catch (GitAPIException e ) {
169
- log .error (e .getMessage (), e );
170
- throw new GitRepoCloneException (e .getMessage ());
201
+ cloneCommand .setDirectory (workspaceDirectory );
202
+ cloneCommand .setBranch (scriptsRepo .getBranch ());
203
+ boolean cloneSuccess = false ;
204
+ int retryCount = 0 ;
205
+ String errMsg = "" ;
206
+ while (!cloneSuccess && retryCount < MAX_RETRY_COUNT ) {
207
+ try {
208
+ cloneCommand .call ();
209
+ cloneSuccess = true ;
210
+ } catch (GitAPIException e ) {
211
+ retryCount ++;
212
+ errMsg =
213
+ String .format ("Cloning scripts form GIT repo error:%s" , e .getMessage ());
214
+ log .error (errMsg );
215
+ }
216
+ }
217
+ if (!cloneSuccess ) {
218
+ throw new GitRepoCloneException (errMsg );
219
+ }
171
220
}
172
221
}
173
222
174
- private void buildDestroyEnv (OpenTofuScriptGitRepoDetails openTofuScriptGitRepoDetails ,
175
- String tfState , UUID uuid ) {
176
- buildDeployEnv (openTofuScriptGitRepoDetails , uuid );
177
- openTofuScriptsHelper .createTfStateFile (tfState ,
178
- uuid + File .separator + openTofuScriptGitRepoDetails .getScriptPath ());
179
- }
180
-
181
223
private String getScriptsLocationInRepo (
182
224
OpenTofuScriptGitRepoDetails openTofuScriptGitRepoDetails ,
183
225
UUID uuid ) {
184
- if (Objects . nonNull (openTofuScriptGitRepoDetails .getScriptPath ())) {
226
+ if (StringUtils . isNotBlank (openTofuScriptGitRepoDetails .getScriptPath ())) {
185
227
return uuid + File .separator + openTofuScriptGitRepoDetails .getScriptPath ();
186
228
}
187
229
return uuid .toString ();
188
230
}
189
231
232
+ private boolean cleanWorkspace (UUID uuid ) {
233
+ boolean cleanSuccess = true ;
234
+ try {
235
+ String workspace = executor .getModuleFullPath (uuid .toString ());
236
+ Path path = Paths .get (workspace ).toAbsolutePath ().normalize ();
237
+ List <File > files =
238
+ Files .walk (path ).sorted (Comparator .reverseOrder ()).map (Path ::toFile ).toList ();
239
+ for (File file : files ) {
240
+ if (!file .delete ()) {
241
+ cleanSuccess = false ;
242
+ log .info ("Failed to delete file: {}" , file .getAbsolutePath ());
243
+ }
244
+ }
245
+ } catch (IOException e ) {
246
+ return false ;
247
+ }
248
+ return cleanSuccess ;
249
+ }
190
250
191
251
}
0 commit comments