66
77import Boom from 'boom' ;
88
9+ import { i18n } from '@kbn/i18n' ;
910import { RequestFacade , ResponseToolkitFacade } from '../..' ;
1011import { validateGitUrl } from '../../common/git_url_utils' ;
1112import { RepositoryUtils } from '../../common/repository_utils' ;
@@ -19,6 +20,7 @@ import { EsClientWithRequest } from '../utils/esclient_with_request';
1920import { CodeServerRouter } from '../security' ;
2021import { CodeServices } from '../distributed/code_services' ;
2122import { RepositoryServiceDefinition } from '../distributed/apis' ;
23+ import { getReferenceHelper } from '../utils/repository_reference_helper' ;
2224
2325export function repositoryRoute (
2426 router : CodeServerRouter ,
@@ -56,12 +58,32 @@ export function repositoryRoute(
5658 try {
5759 // Check if the repository already exists
5860 await repoObjectClient . getRepository ( repo . uri ) ;
61+ // distinguish between that the repository exists in the current space and that the repository exists in
62+ // another space, and return the default message if error happens during reference checking.
63+ try {
64+ const hasRef = await getReferenceHelper ( req . getSavedObjectsClient ( ) ) . hasReference (
65+ repo . uri
66+ ) ;
67+ if ( ! hasRef ) {
68+ return Boom . conflict (
69+ i18n . translate ( 'xpack.code.repositoryManagement.repoOtherSpaceImportedMessage' , {
70+ defaultMessage : 'The repository has already been imported in another space!' ,
71+ } )
72+ ) ;
73+ }
74+ } catch ( e ) {
75+ log . error ( `Failed to check reference for ${ repo . uri } in current space` ) ;
76+ }
5977 const msg = `Repository ${ repoUrl } already exists. Skip clone.` ;
6078 log . info ( msg ) ;
6179 return h . response ( msg ) . code ( 304 ) ; // Not Modified
6280 } catch ( error ) {
6381 log . info ( `Repository ${ repoUrl } does not exist. Go ahead with clone.` ) ;
6482 try {
83+ // create the reference first, and make the creation idempotent, to avoid potential dangling repositories
84+ // which have no references from any space, in case the writes to ES may fail independently
85+ await getReferenceHelper ( req . getSavedObjectsClient ( ) ) . createReference ( repo . uri ) ;
86+
6587 // Create the index for the repository
6688 const initializer = ( await repoIndexInitializerFactory . create (
6789 repo . uri ,
@@ -106,6 +128,9 @@ export function repositoryRoute(
106128 const repoUri : string = req . params . uri as string ;
107129 const repoObjectClient = new RepositoryObjectClient ( new EsClientWithRequest ( req ) ) ;
108130 try {
131+ // make sure the repo belongs to the current space
132+ getReferenceHelper ( req . getSavedObjectsClient ( ) ) . ensureReference ( repoUri ) ;
133+
109134 // Check if the repository already exists. If not, an error will be thrown.
110135 await repoObjectClient . getRepository ( repoUri ) ;
111136
@@ -129,6 +154,9 @@ export function repositoryRoute(
129154 } ;
130155 const endpoint = await codeServices . locate ( req , repoUri ) ;
131156 await repositoryService . delete ( endpoint , payload ) ;
157+
158+ // delete the reference last to avoid dangling repositories
159+ await getReferenceHelper ( req . getSavedObjectsClient ( ) ) . deleteReference ( repoUri ) ;
132160 return { } ;
133161 } catch ( error ) {
134162 const msg = `Issue repository delete request for ${ repoUri } error` ;
@@ -146,6 +174,7 @@ export function repositoryRoute(
146174 async handler ( req : RequestFacade ) {
147175 const repoUri = req . params . uri as string ;
148176 try {
177+ await getReferenceHelper ( req . getSavedObjectsClient ( ) ) . ensureReference ( repoUri ) ;
149178 const repoObjectClient = new RepositoryObjectClient ( new EsClientWithRequest ( req ) ) ;
150179 return await repoObjectClient . getRepository ( repoUri ) ;
151180 } catch ( error ) {
@@ -164,25 +193,30 @@ export function repositoryRoute(
164193 const repoUri = req . params . uri as string ;
165194 try {
166195 const repoObjectClient = new RepositoryObjectClient ( new EsClientWithRequest ( req ) ) ;
167- let gitStatus = null ;
168- try {
169- gitStatus = await repoObjectClient . getRepositoryGitStatus ( repoUri ) ;
170- } catch ( error ) {
171- log . debug ( `Get repository git status ${ repoUri } error: ${ error } ` ) ;
172- }
173196
197+ let gitStatus = null ;
174198 let indexStatus = null ;
175- try {
176- indexStatus = await repoObjectClient . getRepositoryIndexStatus ( repoUri ) ;
177- } catch ( error ) {
178- log . debug ( `Get repository index status ${ repoUri } error: ${ error } ` ) ;
179- }
180-
181199 let deleteStatus = null ;
182- try {
183- deleteStatus = await repoObjectClient . getRepositoryDeleteStatus ( repoUri ) ;
184- } catch ( error ) {
185- log . debug ( `Get repository delete status ${ repoUri } error: ${ error } ` ) ;
200+ const hasRef = await getReferenceHelper ( req . getSavedObjectsClient ( ) ) . hasReference ( repoUri ) ;
201+
202+ if ( hasRef ) {
203+ try {
204+ gitStatus = await repoObjectClient . getRepositoryGitStatus ( repoUri ) ;
205+ } catch ( error ) {
206+ log . debug ( `Get repository git status ${ repoUri } error: ${ error } ` ) ;
207+ }
208+
209+ try {
210+ indexStatus = await repoObjectClient . getRepositoryIndexStatus ( repoUri ) ;
211+ } catch ( error ) {
212+ log . debug ( `Get repository index status ${ repoUri } error: ${ error } ` ) ;
213+ }
214+
215+ try {
216+ deleteStatus = await repoObjectClient . getRepositoryDeleteStatus ( repoUri ) ;
217+ } catch ( error ) {
218+ log . debug ( `Get repository delete status ${ repoUri } error: ${ error } ` ) ;
219+ }
186220 }
187221 return {
188222 gitStatus,
@@ -204,8 +238,9 @@ export function repositoryRoute(
204238 method : 'GET' ,
205239 async handler ( req : RequestFacade ) {
206240 try {
241+ const uris = await getReferenceHelper ( req . getSavedObjectsClient ( ) ) . findReferences ( ) ;
207242 const repoObjectClient = new RepositoryObjectClient ( new EsClientWithRequest ( req ) ) ;
208- return await repoObjectClient . getAllRepositories ( ) ;
243+ return await repoObjectClient . getRepositories ( uris ) ;
209244 } catch ( error ) {
210245 const msg = `Get all repositories error` ;
211246 log . error ( msg ) ;
@@ -226,6 +261,7 @@ export function repositoryRoute(
226261 const repoUri = req . params . uri as string ;
227262 const reindex : boolean = ( req . payload as any ) . reindex ;
228263 try {
264+ await getReferenceHelper ( req . getSavedObjectsClient ( ) ) . ensureReference ( repoUri ) ;
229265 const repoObjectClient = new RepositoryObjectClient ( new EsClientWithRequest ( req ) ) ;
230266 const cloneStatus = await repoObjectClient . getRepositoryGitStatus ( repoUri ) ;
231267
@@ -258,6 +294,7 @@ export function repositoryRoute(
258294
259295 try {
260296 // Check if the repository exists
297+ await getReferenceHelper ( req . getSavedObjectsClient ( ) ) . ensureReference ( repoUri ) ;
261298 await repoObjectClient . getRepository ( repoUri ) ;
262299 } catch ( error ) {
263300 return Boom . badRequest ( `Repository not existed for ${ repoUri } ` ) ;
@@ -284,6 +321,7 @@ export function repositoryRoute(
284321 async handler ( req : RequestFacade ) {
285322 const repoUri = req . params . uri as string ;
286323 try {
324+ await getReferenceHelper ( req . getSavedObjectsClient ( ) ) . ensureReference ( repoUri ) ;
287325 const repoObjectClient = new RepositoryObjectClient ( new EsClientWithRequest ( req ) ) ;
288326 return await repoObjectClient . getRepositoryConfig ( repoUri ) ;
289327 } catch ( error ) {
0 commit comments