@@ -36,15 +36,16 @@ import static com.cloudogu.gitops.config.Config.ContentSchema.ContentRepositoryS
3636// We want to evaluate content last, to allow for changing all other repos
3737class Content extends Feature {
3838
39- protected Config config
40- protected K8sClient k8sClient
41- protected ScmmRepoProvider repoProvider
42- protected ScmmApiClient scmmApiClient
43- protected Jenkins jenkins
39+ private Config config
40+ private K8sClient k8sClient
41+ private ScmmRepoProvider repoProvider
42+ private ScmmApiClient scmmApiClient
43+ private Jenkins jenkins
4444 // set by lazy initialisation
4545 private TemplatingEngine templatingEngine
4646 // used to clone repos in validation phase
4747 private List<RepoCoordinate > cachedRepoCoordinates = new ArrayList<> ()
48+ private File mergedReposFolder
4849
4950 Content (
5051 Config config , K8sClient k8sClient , ScmmRepoProvider repoProvider , ScmmApiClient scmmApiClient , Jenkins jenkins
@@ -70,12 +71,11 @@ class Content extends Feature {
7071
7172 @Override
7273 void validate () {
73- try {
74- cachedRepoCoordinates = cloneContentRepos()
75- } catch (Exception e) {
76- log. error(' Error validate Content Feature' , e)
77- throw new RuntimeException (' Feature content has problem. Please check configuration.' )
78- }
74+ // ensure cache is cleaned
75+ clearCache()
76+ // clones repo to check valid configuration and reuse result for further step.
77+ cachedRepoCoordinates = cloneContentRepos()
78+
7979 }
8080
8181 void createImagePullSecrets () {
@@ -109,14 +109,16 @@ class Content extends Feature {
109109 cachedRepoCoordinates = cloneContentRepos()
110110 }
111111 pushTargetRepos(cachedRepoCoordinates)
112- cachedRepoCoordinates. clear()
112+ // after all, clean folders and list
113+ clearCache()
114+
113115 }
114116
115117 protected List<RepoCoordinate > cloneContentRepos () {
118+ mergedReposFolder = File . createTempDir(' gitops-playground-based-content-repos-' )
116119 List<RepoCoordinate > repoCoordinates = []
117- def mergedReposFolder = File . createTempDir(' gitops-playground-folder-based-content-repos-' )
118- mergedReposFolder. deleteOnExit()
119- log. debug(" Aggregating folder structure for all ${ config.content.repos.size()} folder based-repos" )
120+
121+ log. debug(" Aggregating structure for all ${ config.content.repos.size()} repos." )
120122 config. content. repos. each { repoConfig ->
121123 createRepoCoordinates(repoConfig, mergedReposFolder, repoCoordinates)
122124 }
@@ -132,8 +134,8 @@ class Content extends Feature {
132134 }
133135
134136
135- protected void createRepoCoordinates (ContentRepositorySchema repoConfig , File mergedReposFolder , List<RepoCoordinate > repoCoordinates ) {
136- def repoTmpDir = File . createTempDir(' gitops-playground-folder-based-single- content-repo-' )
137+ private void createRepoCoordinates (ContentRepositorySchema repoConfig , File mergedReposFolder , List<RepoCoordinate > repoCoordinates ) {
138+ def repoTmpDir = File . createTempDir(' gitops-playground-content-repo-' )
137139 log. debug(" Cloning content repo, ${ repoConfig.url} , revision ${ repoConfig.ref} , path ${ repoConfig.path} , overwriteMode ${ repoConfig.overwriteMode} " )
138140
139141 cloneToLocalFolder(repoConfig, repoTmpDir)
@@ -145,44 +147,45 @@ class Content extends Feature {
145147 switch (repoConfig. type) {
146148 case ContentRepoType . FOLDER_BASED :
147149 createRepoCoordinatesForTypeFolderBased(repoConfig, repoTmpDir, contentRepoDir, mergedReposFolder, repoCoordinates)
150+ repoTmpDir. deleteDir()
148151 break
149152 case ContentRepoType . COPY :
150- def repoCoordinate = createRepoCoordinatesForTypeCopy(repoConfig, contentRepoDir, mergedReposFolder, repoTmpDir)
151- addRepoCoordinates(repoCoordinates, repoCoordinate )
153+ def repoCoordinate = createRepoCoordinatesForTypeCopy(repoConfig, contentRepoDir, mergedReposFolder, repoTmpDir, repoCoordinates )
154+ repoTmpDir . deleteDir( )
152155 break
153156 case ContentRepoType . MIRROR :
154- def repoCoordinate = createRepoCoordinateForTypeMirror(repoConfig, repoTmpDir)
155- addRepoCoordinates(repoCoordinates, repoCoordinate)
157+ def repoCoordinate = createRepoCoordinateForTypeMirror(repoConfig, repoTmpDir, repoCoordinates )
158+ // intentionally not deleting repoTmpDir, it is contained in RepoCoordinates for MIRROR usage
156159 break
157160 }
158161 log. debug(" Finished cloning content repos. repoCoordinates=${ repoCoordinates} " )
159162 }
160163
161- private static RepoCoordinate createRepoCoordinatesForTypeCopy (ContentRepositorySchema repoConfig , File contentRepoDir , File mergedReposFolder , File repoTmpDir ) {
164+ private static void createRepoCoordinatesForTypeCopy (ContentRepositorySchema repoConfig , File contentRepoDir , File mergedReposFolder , File repoTmpDir , List< RepoCoordinate > repoCoordinates ) {
162165 String namespace = repoConfig. target. split(' /' )[0 ]
163166 String repoName = repoConfig. target. split(' /' )[1 ]
164167
165168 def repoCoordinate = mergeRepoDirs(contentRepoDir, namespace, repoName, mergedReposFolder, repoConfig)
166169 repoCoordinate. refIsTag = isTag(repoTmpDir, repoConfig. ref)
167- return repoCoordinate
170+ addRepoCoordinates(repoCoordinates, repoCoordinate)
168171 }
169172
170173 private static void createRepoCoordinatesForTypeFolderBased (ContentRepositorySchema repoConfig , File repoTmpDir , File contentRepoDir , File mergedReposFolder , List<RepoCoordinate > repoCoordinates ) {
171174 boolean refIsTag = isTag(repoTmpDir, repoConfig. ref)
172175 findRepoDirectories(contentRepoDir)
173176 .each { contentRepoNamespaceDir ->
174177 findRepoDirectories(contentRepoNamespaceDir)
175- .each { contentRepoRepoDir ->
178+ .each { contentRepoFolder ->
176179 String namespace = contentRepoNamespaceDir. name
177- String repoName = contentRepoRepoDir . name
178- def repoCoordinate = mergeRepoDirs(contentRepoRepoDir , namespace, repoName, mergedReposFolder, repoConfig)
180+ String repoName = contentRepoFolder . name
181+ def repoCoordinate = mergeRepoDirs(contentRepoFolder , namespace, repoName, mergedReposFolder, repoConfig)
179182 repoCoordinate. refIsTag = refIsTag
180183 addRepoCoordinates(repoCoordinates, repoCoordinate)
181184 }
182185 }
183186 }
184187
185- private static RepoCoordinate createRepoCoordinateForTypeMirror (ContentRepositorySchema repoConfig , File repoTmpDir ) {
188+ private static void createRepoCoordinateForTypeMirror (ContentRepositorySchema repoConfig , File repoTmpDir , List< RepoCoordinate > repoCoordinates ) {
186189 // Don't merge but keep these in separate dirs.
187190 // This avoids messing up .git folders with possible confusing exceptions for the user
188191 String namespace = repoConfig. target. split(' /' )[0 ]
@@ -194,7 +197,7 @@ class Content extends Feature {
194197 repoConfig : repoConfig,
195198 refIsTag : isTag(repoTmpDir, repoConfig. ref)
196199 )
197- return repoCoordinate
200+ addRepoCoordinates(repoCoordinates, repoCoordinate)
198201 }
199202
200203 /**
@@ -253,8 +256,10 @@ class Content extends Feature {
253256
254257 if (ContentRepoType . MIRROR == repoConfig. type) {
255258 def fetch = git. fetch()
256- // fetch also needs CredentialProvider, jgit behaviour.
257- fetch. setCredentialsProvider(new UsernamePasswordCredentialsProvider (repoConfig. username, repoConfig. password))
259+ if (repoConfig. username != null && repoConfig. password != null ) {
260+ // fetch also needs CredentialProvider, jgit behaviour.
261+ fetch. setCredentialsProvider(new UsernamePasswordCredentialsProvider (repoConfig. username, repoConfig. password))
262+ }
258263 fetch. setRefSpecs(" +refs/*:refs/*" ). call() // Fetch all branches and tags
259264 }
260265
@@ -295,7 +300,7 @@ class Content extends Feature {
295300 }
296301
297302
298- protected void pushTargetRepos (List<RepoCoordinate > repoCoordinates ) {
303+ private void pushTargetRepos (List<RepoCoordinate > repoCoordinates ) {
299304 repoCoordinates. each { repoCoordinate ->
300305
301306 ScmmRepo targetRepo = repoProvider. getRepo(repoCoordinate. fullRepoName)
@@ -327,7 +332,7 @@ class Content extends Feature {
327332 * Copies repoCoordinate to targetRepo, commits and pushes
328333 * Same logic for both FOLDER_BASED and COPY repo types.
329334 */
330- protected static void handleRepoCopyingOrFolderBased (RepoCoordinate repoCoordinate , ScmmRepo targetRepo ) {
335+ private static void handleRepoCopyingOrFolderBased (RepoCoordinate repoCoordinate , ScmmRepo targetRepo ) {
331336 clearTargetRepoIfApplicable(repoCoordinate, targetRepo)
332337 // Avoid overwriting .git in target to avoid, because we don't need it for copying and
333338 // git pack files are typically read-only, leading to IllegalArgumentException:
@@ -345,7 +350,7 @@ class Content extends Feature {
345350
346351 }
347352
348- protected static String setRefSpec (RepoCoordinate repoCoordinate , String targetRefShort ) {
353+ private static String setRefSpec (RepoCoordinate repoCoordinate , String targetRefShort ) {
349354 String refSpec
350355 if ((repoCoordinate. refIsTag && ! repoCoordinate. repoConfig. targetRef. startsWith(' refs/heads' ))
351356 || repoCoordinate. repoConfig. targetRef. startsWith(' refs/tags' )) {
@@ -372,7 +377,7 @@ class Content extends Feature {
372377 /**
373378 * Force pushes repoCoordinate.repoConfig.ref or all refs to targetRepo
374379 */
375- protected static void handleRepoMirroring (RepoCoordinate repoCoordinate , ScmmRepo targetRepo ) {
380+ private static void handleRepoMirroring (RepoCoordinate repoCoordinate , ScmmRepo targetRepo ) {
376381 try (def targetGit = Git . open(new File (targetRepo. absoluteLocalRepoTmpDir))) {
377382 def remoteUrl = targetGit. repository. config. getString(' remote' , ' origin' , ' url' )
378383
@@ -415,7 +420,7 @@ class Content extends Feature {
415420 }
416421 }
417422
418- protected void createJenkinsJobIfApplicable (RepoCoordinate repoCoordinate , ScmmRepo repo ) {
423+ private void createJenkinsJobIfApplicable (RepoCoordinate repoCoordinate , ScmmRepo repo ) {
419424 if (repoCoordinate. repoConfig. createJenkinsJob && jenkins. isEnabled()) {
420425 if (existFileInSomeBranch(repo. absoluteLocalRepoTmpDir, ' Jenkinsfile' )) {
421426 jenkins. createJenkinsjob(repoCoordinate. namespace, repoCoordinate. namespace)
@@ -545,6 +550,14 @@ class Content extends Feature {
545550 return true
546551 }
547552
553+ private void clearCache () {
554+ if (mergedReposFolder) {
555+ mergedReposFolder. deleteDir()
556+ }
557+ cachedRepoCoordinates. clear()
558+ mergedReposFolder = null
559+ }
560+
548561 static class RepoCoordinate {
549562 String namespace
550563 String repoName
0 commit comments