import { get } from 'lodash' ; import { Client } from 'elasticsearch' ; import { ToolingLog } from '@osd/dev-utils' ; import { Stats } from '../stats' ; const PENDING_SNAPSHOT_STATUSES = [ 'INIT' , 'STARTED' , 'WAITING' ] ; export async function deleteIndex ( options ) { const { client , stats , index , log , retryIfSnapshottingCount = 10 } = options ; const getIndicesToDelete = async ( ) => { const aliasInfo = await client . indices . getAlias ( { name : index , ignore : [ 404 ] } ) ; return aliasInfo . status === 404 ? [ index ] : Object . keys ( aliasInfo ) ; } ; try { const indicesToDelete = await getIndicesToDelete ( ) ; await client . indices . delete ( { index : indicesToDelete } ) ; for ( let i = 0 ; i < indicesToDelete . length ; i ++ ) { const indexToDelete = indicesToDelete [ i ] ; stats . deletedIndex ( indexToDelete ) ; } } catch ( error ) { if ( retryIfSnapshottingCount > 0 && isDeleteWhileSnapshotInProgressError ( error ) ) { stats . waitingForInProgressSnapshot ( index ) ; await waitForSnapshotCompletion ( client , index , log ) ; return await deleteIndex ( { ... options , retryIfSnapshottingCount : retryIfSnapshottingCount - 1 , } ) ; } if ( get ( error , 'body.error.type' ) !== 'index_not_found_exception' ) { throw error ; } } } param { Error } error return { Boolean } export function isDeleteWhileSnapshotInProgressError ( error ) { return get ( error , 'body.error.reason' , '' ) . startsWith ( 'Cannot delete indices that are being snapshotted' ) ; } /**
 * Wait for the any snapshot in any repository that is
 * snapshotting this index to complete.
 */ export async function waitForSnapshotCompletion ( client , index , log ) { const isSnapshotPending = async ( repository , snapshot ) => { const { snapshots : [ status ] , } = await client . snapshot . status ( { repository , snapshot , } ) ; log . debug ( `Snapshot ${ repository }/${ snapshot } is ${ status . state }` ) ; return PENDING_SNAPSHOT_STATUSES . includes ( status . state ) ; } ; const getInProgressSnapshots = async ( repository ) => { const { snapshots : inProgressSnapshots } = await client . snapshot . get ( { repository , snapshot : '_current' , } ) ; return inProgressSnapshots ; } ; for ( const repository of Object . keys ( await client . snapshot . getRepository ( { } as any ) ) ) { const allInProgress = await getInProgressSnapshots ( repository ) ; const found = allInProgress . find ( ( s ) => s . indices . includes ( index ) ) ; if ( ! found ) { continue ; } while ( await isSnapshotPending ( repository , found . snapshot ) ) { await new Promise ( ( resolve ) => setTimeout ( resolve , 500 ) ) ; } return ; } }