@@ -287,14 +287,7 @@ public ClusterState execute(ClusterState currentState) {
287287 "cannot snapshot while a snapshot deletion is in-progress in [" + deletionsInProgress + "]"
288288 );
289289 }
290- final RepositoryCleanupInProgress repositoryCleanupInProgress = currentState .custom (RepositoryCleanupInProgress .TYPE );
291- if (repositoryCleanupInProgress != null && repositoryCleanupInProgress .hasCleanupInProgress ()) {
292- throw new ConcurrentSnapshotExecutionException (
293- repositoryName ,
294- snapshotName ,
295- "cannot snapshot while a repository cleanup is in-progress in [" + repositoryCleanupInProgress + "]"
296- );
297- }
290+ ensureNoCleanupInProgress (currentState , repositoryName , snapshotName , "create snapshot" );
298291 SnapshotsInProgress snapshots = currentState .custom (SnapshotsInProgress .TYPE );
299292 // Fail if there are any concurrently running snapshots. The only exception to this being a snapshot in INIT state from
300293 // a
@@ -497,7 +490,7 @@ public ClusterState execute(ClusterState currentState) {
497490 if (concurrentOperationsAllowed == false && runningSnapshots .stream ().anyMatch (entry -> entry .state () != State .INIT )) {
498491 throw new ConcurrentSnapshotExecutionException (repositoryName , snapshotName , " a snapshot is already running" );
499492 }
500- ensureNoCleanupInProgress (currentState , repositoryName , snapshotName );
493+ ensureNoCleanupInProgress (currentState , repositoryName , snapshotName , "create snapshot" );
501494 ensureBelowConcurrencyLimit (repositoryName , snapshotName , snapshots , deletionsInProgress );
502495 // Store newSnapshot here to be processed in clusterStateProcessed
503496 List <String > indices = Arrays .asList (indexNameExpressionResolver .concreteIndexNames (currentState , request ));
@@ -657,7 +650,7 @@ public void cloneSnapshot(CloneSnapshotRequest request, ActionListener<Void> lis
657650 public ClusterState execute (ClusterState currentState ) {
658651 ensureRepositoryExists (repositoryName , currentState );
659652 ensureSnapshotNameAvailableInRepo (repositoryData , snapshotName , repository );
660- ensureNoCleanupInProgress (currentState , repositoryName , snapshotName );
653+ ensureNoCleanupInProgress (currentState , repositoryName , snapshotName , "clone snapshot" );
661654 final SnapshotsInProgress snapshots = currentState .custom (SnapshotsInProgress .TYPE , SnapshotsInProgress .EMPTY );
662655 final List <SnapshotsInProgress .Entry > runningSnapshots = snapshots .entries ();
663656 ensureSnapshotNameNotRunning (runningSnapshots , repositoryName , snapshotName );
@@ -730,7 +723,12 @@ public void clusterStateProcessed(String source, ClusterState oldState, final Cl
730723 }, "clone_snapshot [" + request .source () + "][" + snapshotName + ']' , listener ::onFailure );
731724 }
732725
733- private static void ensureNoCleanupInProgress (ClusterState currentState , String repositoryName , String snapshotName ) {
726+ private static void ensureNoCleanupInProgress (
727+ final ClusterState currentState ,
728+ final String repositoryName ,
729+ final String snapshotName ,
730+ final String reason
731+ ) {
734732 final RepositoryCleanupInProgress repositoryCleanupInProgress = currentState .custom (
735733 RepositoryCleanupInProgress .TYPE ,
736734 RepositoryCleanupInProgress .EMPTY
@@ -739,7 +737,13 @@ private static void ensureNoCleanupInProgress(ClusterState currentState, String
739737 throw new ConcurrentSnapshotExecutionException (
740738 repositoryName ,
741739 snapshotName ,
742- "cannot snapshot while a repository cleanup is in-progress in [" + repositoryCleanupInProgress + "]"
740+ "cannot "
741+ + reason
742+ + " while a repository cleanup is in-progress in "
743+ + repositoryCleanupInProgress .entries ()
744+ .stream ()
745+ .map (RepositoryCleanupInProgress .Entry ::repository )
746+ .collect (Collectors .toSet ())
743747 );
744748 }
745749 }
@@ -2508,18 +2512,17 @@ private void failSnapshotCompletionListeners(Snapshot snapshot, Exception e) {
25082512 * @param listener listener
25092513 */
25102514 public void deleteSnapshots (final DeleteSnapshotRequest request , final ActionListener <Void > listener ) {
2511-
2515+ final String repositoryName = request . repository ();
25122516 final String [] snapshotNames = request .snapshots ();
2513- final String repoName = request .repository ();
25142517 logger .info (
25152518 () -> new ParameterizedMessage (
25162519 "deleting snapshots [{}] from repository [{}]" ,
25172520 Strings .arrayToCommaDelimitedString (snapshotNames ),
2518- repoName
2521+ repositoryName
25192522 )
25202523 );
25212524
2522- final Repository repository = repositoriesService .repository (repoName );
2525+ final Repository repository = repositoriesService .repository (repositoryName );
25232526 final String taskDescription = "delete snapshot [" + repository + "]" + Arrays .toString (snapshotNames );
25242527 repository .executeConsistentStateUpdate (repositoryData -> new ClusterStateUpdateTask (request .masterNodeTimeout ()) {
25252528
@@ -2543,17 +2546,46 @@ public ClusterState execute(ClusterState currentState) throws Exception {
25432546 + "]"
25442547 );
25452548 }
2546- ensureRepositoryExists (repoName , currentState );
2547- final SnapshotsInProgress snapshots = currentState .custom (SnapshotsInProgress .TYPE , SnapshotsInProgress .EMPTY );
2548- final List <SnapshotsInProgress .Entry > snapshotEntries = findInProgressSnapshots (snapshots , snapshotNames , repoName );
2549- final List <SnapshotId > snapshotIds = matchingSnapshotIds (
2550- snapshotEntries .stream ().map (e -> e .snapshot ().getSnapshotId ()).collect (Collectors .toList ()),
2551- repositoryData ,
2552- snapshotNames ,
2553- repoName
2554- );
2549+ ensureRepositoryExists (repositoryName , currentState );
2550+ final List <SnapshotId > snapshotIds = new ArrayList <>();
2551+ final List <SnapshotsInProgress .Entry > snapshotEntries = new ArrayList <>();
2552+
2553+ // find in-progress snapshots to delete in cluster state
2554+ final SnapshotsInProgress snapshotsInProgress = currentState .custom (SnapshotsInProgress .TYPE , SnapshotsInProgress .EMPTY );
2555+ for (SnapshotsInProgress .Entry entry : snapshotsInProgress .entries ()) {
2556+ final SnapshotId snapshotId = entry .snapshot ().getSnapshotId ();
2557+ if (entry .repository ().equals (repositoryName ) && Regex .simpleMatch (snapshotNames , snapshotId .getName ())) {
2558+ snapshotIds .add (snapshotId );
2559+ snapshotEntries .add (entry );
2560+ }
2561+ }
2562+
2563+ // find snapshots to delete in repository data
2564+ final Map <String , SnapshotId > snapshotsIdsInRepository = repositoryData .getSnapshotIds ()
2565+ .stream ()
2566+ .collect (Collectors .toMap (SnapshotId ::getName , Function .identity ()));
2567+ for (String snapshotOrPattern : snapshotNames ) {
2568+ if (Regex .isSimpleMatchPattern (snapshotOrPattern )) {
2569+ for (Map .Entry <String , SnapshotId > entry : snapshotsIdsInRepository .entrySet ()) {
2570+ if (Regex .simpleMatch (snapshotOrPattern , entry .getKey ())) {
2571+ snapshotIds .add (entry .getValue ());
2572+ }
2573+ }
2574+ } else {
2575+ final SnapshotId foundId = snapshotsIdsInRepository .get (snapshotOrPattern );
2576+ if (foundId == null ) {
2577+ if (snapshotEntries .stream ()
2578+ .noneMatch (entry -> entry .snapshot ().getSnapshotId ().getName ().equals (snapshotOrPattern ))) {
2579+ throw new SnapshotMissingException (repositoryName , snapshotOrPattern );
2580+ }
2581+ } else {
2582+ snapshotIds .add (foundId );
2583+ }
2584+ }
2585+ }
2586+
25552587 if (snapshotEntries .isEmpty () || minNodeVersion .onOrAfter (SnapshotsService .FULL_CONCURRENCY_VERSION )) {
2556- deleteFromRepoTask = createDeleteStateUpdate (snapshotIds , repoName , repositoryData , Priority .NORMAL , listener );
2588+ deleteFromRepoTask = createDeleteStateUpdate (snapshotIds , repositoryName , repositoryData , Priority .NORMAL , listener );
25572589 return deleteFromRepoTask .execute (currentState );
25582590 }
25592591 assert snapshotEntries .size () == 1 : "Expected just a single running snapshot but saw " + snapshotEntries ;
@@ -2608,7 +2640,7 @@ public ClusterState execute(ClusterState currentState) throws Exception {
26082640 .putCustom (
26092641 SnapshotsInProgress .TYPE ,
26102642 SnapshotsInProgress .of (
2611- snapshots .entries ()
2643+ snapshotsInProgress .entries ()
26122644 .stream ()
26132645 // remove init state snapshot we found from a previous master if there was one
26142646 .filter (existing -> abortedDuringInit == false || existing .equals (snapshotEntry ) == false )
@@ -2648,7 +2680,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS
26482680 } else {
26492681 clusterService .submitStateUpdateTask (
26502682 taskDescription ,
2651- createDeleteStateUpdate (outstandingDeletes , repoName , repositoryData , Priority .IMMEDIATE , listener )
2683+ createDeleteStateUpdate (outstandingDeletes , repositoryName , repositoryData , Priority .IMMEDIATE , listener )
26522684 );
26532685 }
26542686 return ;
@@ -2658,7 +2690,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS
26582690 logger .debug ("deleted snapshot completed - deleting files" );
26592691 clusterService .submitStateUpdateTask (
26602692 taskDescription ,
2661- createDeleteStateUpdate (outstandingDeletes , repoName , result .v1 (), Priority .IMMEDIATE , listener )
2693+ createDeleteStateUpdate (outstandingDeletes , repositoryName , result .v1 (), Priority .IMMEDIATE , listener )
26622694 );
26632695 }, e -> {
26642696 if (ExceptionsHelper .unwrap (e , NotMasterException .class , FailedToCommitClusterStateException .class ) != null ) {
@@ -2676,52 +2708,6 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS
26762708 }, taskDescription , listener ::onFailure );
26772709 }
26782710
2679- private static List <SnapshotId > matchingSnapshotIds (
2680- List <SnapshotId > inProgress ,
2681- RepositoryData repositoryData ,
2682- String [] snapshotsOrPatterns ,
2683- String repositoryName
2684- ) {
2685- final Map <String , SnapshotId > allSnapshotIds = repositoryData .getSnapshotIds ()
2686- .stream ()
2687- .collect (Collectors .toMap (SnapshotId ::getName , Function .identity ()));
2688- final Set <SnapshotId > foundSnapshots = new HashSet <>(inProgress );
2689- for (String snapshotOrPattern : snapshotsOrPatterns ) {
2690- if (Regex .isSimpleMatchPattern (snapshotOrPattern )) {
2691- for (Map .Entry <String , SnapshotId > entry : allSnapshotIds .entrySet ()) {
2692- if (Regex .simpleMatch (snapshotOrPattern , entry .getKey ())) {
2693- foundSnapshots .add (entry .getValue ());
2694- }
2695- }
2696- } else {
2697- final SnapshotId foundId = allSnapshotIds .get (snapshotOrPattern );
2698- if (foundId == null ) {
2699- if (inProgress .stream ().noneMatch (snapshotId -> snapshotId .getName ().equals (snapshotOrPattern ))) {
2700- throw new SnapshotMissingException (repositoryName , snapshotOrPattern );
2701- }
2702- } else {
2703- foundSnapshots .add (allSnapshotIds .get (snapshotOrPattern ));
2704- }
2705- }
2706- }
2707- return Collections .unmodifiableList (new ArrayList <>(foundSnapshots ));
2708- }
2709-
2710- // Return in-progress snapshot entries by name and repository in the given cluster state or null if none is found
2711- private static List <SnapshotsInProgress .Entry > findInProgressSnapshots (
2712- SnapshotsInProgress snapshots ,
2713- String [] snapshotNames ,
2714- String repositoryName
2715- ) {
2716- List <SnapshotsInProgress .Entry > entries = new ArrayList <>();
2717- for (SnapshotsInProgress .Entry entry : snapshots .entries ()) {
2718- if (entry .repository ().equals (repositoryName ) && Regex .simpleMatch (snapshotNames , entry .snapshot ().getSnapshotId ().getName ())) {
2719- entries .add (entry );
2720- }
2721- }
2722- return entries ;
2723- }
2724-
27252711 private ClusterStateUpdateTask createDeleteStateUpdate (
27262712 List <SnapshotId > snapshotIds ,
27272713 String repoName ,
@@ -2777,16 +2763,7 @@ public ClusterState execute(ClusterState currentState) {
27772763 );
27782764 }
27792765 }
2780- final RepositoryCleanupInProgress repositoryCleanupInProgress = currentState .custom (
2781- RepositoryCleanupInProgress .TYPE ,
2782- RepositoryCleanupInProgress .EMPTY
2783- );
2784- if (repositoryCleanupInProgress .hasCleanupInProgress ()) {
2785- throw new ConcurrentSnapshotExecutionException (
2786- new Snapshot (repoName , snapshotIds .get (0 )),
2787- "cannot delete snapshots while a repository cleanup is in-progress in [" + repositoryCleanupInProgress + "]"
2788- );
2789- }
2766+ ensureNoCleanupInProgress (currentState , repoName , snapshotIds .get (0 ).getName (), "delete snapshot" );
27902767 final RestoreInProgress restoreInProgress = currentState .custom (RestoreInProgress .TYPE , RestoreInProgress .EMPTY );
27912768 // don't allow snapshot deletions while a restore is taking place,
27922769 // otherwise we could end up deleting a snapshot that is being restored
0 commit comments