@@ -302,7 +302,7 @@ public ClusterState execute(ClusterState currentState) {
302302 SnapshotDeletionsInProgress .TYPE ,
303303 SnapshotDeletionsInProgress .EMPTY
304304 );
305- ensureNoCleanupInProgress (currentState , repositoryName , snapshotName );
305+ ensureNoCleanupInProgress (currentState , repositoryName , snapshotName , "create snapshot" );
306306 ensureBelowConcurrencyLimit (repositoryName , snapshotName , snapshots , deletionsInProgress );
307307 // Store newSnapshot here to be processed in clusterStateProcessed
308308 List <String > indices = Arrays .asList (indexNameExpressionResolver .concreteIndexNames (currentState , request ));
@@ -461,7 +461,7 @@ public void cloneSnapshot(CloneSnapshotRequest request, ActionListener<Void> lis
461461 public ClusterState execute (ClusterState currentState ) {
462462 ensureRepositoryExists (repositoryName , currentState );
463463 ensureSnapshotNameAvailableInRepo (repositoryData , snapshotName , repository );
464- ensureNoCleanupInProgress (currentState , repositoryName , snapshotName );
464+ ensureNoCleanupInProgress (currentState , repositoryName , snapshotName , "clone snapshot" );
465465 final SnapshotsInProgress snapshots = currentState .custom (SnapshotsInProgress .TYPE , SnapshotsInProgress .EMPTY );
466466 final List <SnapshotsInProgress .Entry > runningSnapshots = snapshots .entries ();
467467 ensureSnapshotNameNotRunning (runningSnapshots , repositoryName , snapshotName );
@@ -534,7 +534,12 @@ public void clusterStateProcessed(String source, ClusterState oldState, final Cl
534534 }, "clone_snapshot [" + request .source () + "][" + snapshotName + ']' , listener ::onFailure );
535535 }
536536
537- private static void ensureNoCleanupInProgress (ClusterState currentState , String repositoryName , String snapshotName ) {
537+ private static void ensureNoCleanupInProgress (
538+ final ClusterState currentState ,
539+ final String repositoryName ,
540+ final String snapshotName ,
541+ final String reason
542+ ) {
538543 final RepositoryCleanupInProgress repositoryCleanupInProgress = currentState .custom (
539544 RepositoryCleanupInProgress .TYPE ,
540545 RepositoryCleanupInProgress .EMPTY
@@ -543,7 +548,13 @@ private static void ensureNoCleanupInProgress(ClusterState currentState, String
543548 throw new ConcurrentSnapshotExecutionException (
544549 repositoryName ,
545550 snapshotName ,
546- "cannot snapshot while a repository cleanup is in-progress in [" + repositoryCleanupInProgress + "]"
551+ "cannot "
552+ + reason
553+ + " while a repository cleanup is in-progress in "
554+ + repositoryCleanupInProgress .entries ()
555+ .stream ()
556+ .map (RepositoryCleanupInProgress .Entry ::repository )
557+ .collect (Collectors .toSet ())
547558 );
548559 }
549560 }
@@ -2021,18 +2032,17 @@ private void failSnapshotCompletionListeners(Snapshot snapshot, Exception e) {
20212032 * @param listener listener
20222033 */
20232034 public void deleteSnapshots (final DeleteSnapshotRequest request , final ActionListener <Void > listener ) {
2024-
2035+ final String repositoryName = request . repository ();
20252036 final String [] snapshotNames = request .snapshots ();
2026- final String repoName = request .repository ();
20272037 logger .info (
20282038 () -> new ParameterizedMessage (
20292039 "deleting snapshots [{}] from repository [{}]" ,
20302040 Strings .arrayToCommaDelimitedString (snapshotNames ),
2031- repoName
2041+ repositoryName
20322042 )
20332043 );
20342044
2035- final Repository repository = repositoriesService .repository (repoName );
2045+ final Repository repository = repositoriesService .repository (repositoryName );
20362046 repository .executeConsistentStateUpdate (repositoryData -> new ClusterStateUpdateTask (request .masterNodeTimeout ()) {
20372047
20382048 private SnapshotDeletionsInProgress .Entry newDelete = null ;
@@ -2049,61 +2059,87 @@ public void deleteSnapshots(final DeleteSnapshotRequest request, final ActionLis
20492059
20502060 @ Override
20512061 public ClusterState execute (ClusterState currentState ) {
2052- ensureRepositoryExists (repoName , currentState );
2053- final SnapshotsInProgress snapshots = currentState .custom (SnapshotsInProgress .TYPE , SnapshotsInProgress .EMPTY );
2054- final List <SnapshotsInProgress .Entry > snapshotEntries = findInProgressSnapshots (snapshots , snapshotNames , repoName );
2055- final List <SnapshotId > snapshotIds = matchingSnapshotIds (
2056- snapshotEntries .stream ().map (e -> e .snapshot ().getSnapshotId ()).collect (Collectors .toList ()),
2057- repositoryData ,
2058- snapshotNames ,
2059- repoName
2060- );
2062+ ensureRepositoryExists (repositoryName , currentState );
2063+ final Set <SnapshotId > snapshotIds = new HashSet <>();
2064+
2065+ // find in-progress snapshots to delete in cluster state
2066+ final SnapshotsInProgress snapshotsInProgress = currentState .custom (SnapshotsInProgress .TYPE , SnapshotsInProgress .EMPTY );
2067+ for (SnapshotsInProgress .Entry entry : snapshotsInProgress .entries ()) {
2068+ final SnapshotId snapshotId = entry .snapshot ().getSnapshotId ();
2069+ if (entry .repository ().equals (repositoryName ) && Regex .simpleMatch (snapshotNames , snapshotId .getName ())) {
2070+ snapshotIds .add (snapshotId );
2071+ }
2072+ }
2073+
2074+ // find snapshots to delete in repository data
2075+ final Map <String , SnapshotId > snapshotsIdsInRepository = repositoryData .getSnapshotIds ()
2076+ .stream ()
2077+ .collect (Collectors .toMap (SnapshotId ::getName , Function .identity ()));
2078+ for (String snapshotOrPattern : snapshotNames ) {
2079+ if (Regex .isSimpleMatchPattern (snapshotOrPattern )) {
2080+ for (Map .Entry <String , SnapshotId > entry : snapshotsIdsInRepository .entrySet ()) {
2081+ if (Regex .simpleMatch (snapshotOrPattern , entry .getKey ())) {
2082+ snapshotIds .add (entry .getValue ());
2083+ }
2084+ }
2085+ } else {
2086+ final SnapshotId foundId = snapshotsIdsInRepository .get (snapshotOrPattern );
2087+ if (foundId == null ) {
2088+ if (snapshotIds .stream ().noneMatch (snapshotId -> snapshotId .getName ().equals (snapshotOrPattern ))) {
2089+ throw new SnapshotMissingException (repositoryName , snapshotOrPattern );
2090+ }
2091+ } else {
2092+ snapshotIds .add (foundId );
2093+ }
2094+ }
2095+ }
2096+
20612097 if (snapshotIds .isEmpty ()) {
20622098 return currentState ;
20632099 }
2064- final Set <SnapshotId > activeCloneSources = snapshots .entries ()
2100+
2101+ final Set <SnapshotId > activeCloneSources = snapshotsInProgress .entries ()
20652102 .stream ()
20662103 .filter (SnapshotsInProgress .Entry ::isClone )
20672104 .map (SnapshotsInProgress .Entry ::source )
20682105 .collect (Collectors .toSet ());
20692106 for (SnapshotId snapshotId : snapshotIds ) {
20702107 if (activeCloneSources .contains (snapshotId )) {
20712108 throw new ConcurrentSnapshotExecutionException (
2072- new Snapshot (repoName , snapshotId ),
2109+ new Snapshot (repositoryName , snapshotId ),
20732110 "cannot delete snapshot while it is being cloned"
20742111 );
20752112 }
20762113 }
2114+
2115+ ensureNoCleanupInProgress (
2116+ currentState ,
2117+ repositoryName ,
2118+ snapshotIds .stream ().findFirst ().get ().getName (),
2119+ "delete snapshot"
2120+ );
2121+
20772122 final SnapshotDeletionsInProgress deletionsInProgress = currentState .custom (
20782123 SnapshotDeletionsInProgress .TYPE ,
20792124 SnapshotDeletionsInProgress .EMPTY
20802125 );
2081- final RepositoryCleanupInProgress repositoryCleanupInProgress = currentState .custom (
2082- RepositoryCleanupInProgress .TYPE ,
2083- RepositoryCleanupInProgress .EMPTY
2084- );
2085- if (repositoryCleanupInProgress .hasCleanupInProgress ()) {
2086- throw new ConcurrentSnapshotExecutionException (
2087- new Snapshot (repoName , snapshotIds .get (0 )),
2088- "cannot delete snapshots while a repository cleanup is in-progress in [" + repositoryCleanupInProgress + "]"
2089- );
2090- }
2126+
20912127 final RestoreInProgress restoreInProgress = currentState .custom (RestoreInProgress .TYPE , RestoreInProgress .EMPTY );
20922128 // don't allow snapshot deletions while a restore is taking place,
20932129 // otherwise we could end up deleting a snapshot that is being restored
20942130 // and the files the restore depends on would all be gone
20952131
20962132 for (RestoreInProgress .Entry entry : restoreInProgress ) {
2097- if (repoName .equals (entry .snapshot ().getRepository ()) && snapshotIds .contains (entry .snapshot ().getSnapshotId ())) {
2133+ if (repositoryName .equals (entry .snapshot ().getRepository ()) && snapshotIds .contains (entry .snapshot ().getSnapshotId ())) {
20982134 throw new ConcurrentSnapshotExecutionException (
2099- new Snapshot (repoName , snapshotIds .get (0 )),
2135+ new Snapshot (repositoryName , snapshotIds .stream (). findFirst (). get ()),
21002136 "cannot delete snapshot during a restore in progress in [" + restoreInProgress + "]"
21012137 );
21022138 }
21032139 }
21042140 // Snapshot ids that will have to be physically deleted from the repository
21052141 final Set <SnapshotId > snapshotIdsRequiringCleanup = new HashSet <>(snapshotIds );
2106- final SnapshotsInProgress updatedSnapshots = SnapshotsInProgress .of (snapshots .entries ().stream ().map (existing -> {
2142+ final SnapshotsInProgress updatedSnapshots = SnapshotsInProgress .of (snapshotsInProgress .entries ().stream ().map (existing -> {
21072143 if (existing .state () == State .STARTED && snapshotIdsRequiringCleanup .contains (existing .snapshot ().getSnapshotId ())) {
21082144 // snapshot is started - mark every non completed shard as aborted
21092145 final SnapshotsInProgress .Entry abortedEntry = existing .abort ();
@@ -2130,14 +2166,15 @@ public ClusterState execute(ClusterState currentState) {
21302166 // add the snapshot deletion to the cluster state
21312167 final SnapshotDeletionsInProgress .Entry replacedEntry = deletionsInProgress .getEntries ()
21322168 .stream ()
2133- .filter (entry -> entry .repository ().equals (repoName ) && entry .state () == SnapshotDeletionsInProgress .State .WAITING )
2169+ .filter (entry -> entry .repository ().equals (repositoryName ))
2170+ .filter (entry -> entry .state () == SnapshotDeletionsInProgress .State .WAITING )
21342171 .findFirst ()
21352172 .orElse (null );
21362173 if (replacedEntry == null ) {
21372174 final Optional <SnapshotDeletionsInProgress .Entry > foundDuplicate = deletionsInProgress .getEntries ()
21382175 .stream ()
21392176 .filter (
2140- entry -> entry .repository ().equals (repoName )
2177+ entry -> entry .repository ().equals (repositoryName )
21412178 && entry .state () == SnapshotDeletionsInProgress .State .STARTED
21422179 && entry .getSnapshots ().containsAll (snapshotIds )
21432180 )
@@ -2149,14 +2186,14 @@ public ClusterState execute(ClusterState currentState) {
21492186 }
21502187 newDelete = new SnapshotDeletionsInProgress .Entry (
21512188 List .copyOf (snapshotIdsRequiringCleanup ),
2152- repoName ,
2189+ repositoryName ,
21532190 threadPool .absoluteTimeInMillis (),
21542191 repositoryData .getGenId (),
21552192 updatedSnapshots .entries ()
21562193 .stream ()
2157- .filter (entry -> repoName .equals (entry .repository ()))
2194+ .filter (entry -> repositoryName .equals (entry .repository ()))
21582195 .noneMatch (SnapshotsService ::isWritingToRepository )
2159- && deletionsInProgress .hasExecutingDeletion (repoName ) == false
2196+ && deletionsInProgress .hasExecutingDeletion (repositoryName ) == false
21602197 ? SnapshotDeletionsInProgress .State .STARTED
21612198 : SnapshotDeletionsInProgress .State .WAITING
21622199 );
@@ -2193,7 +2230,7 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS
21932230 return ;
21942231 }
21952232 if (newDelete .state () == SnapshotDeletionsInProgress .State .STARTED ) {
2196- if (tryEnterRepoLoop (repoName )) {
2233+ if (tryEnterRepoLoop (repositoryName )) {
21972234 deleteSnapshotsFromRepository (newDelete , repositoryData , newState .nodes ().getMinNodeVersion ());
21982235 } else {
21992236 logger .trace ("Delete [{}] could not execute directly and was queued" , newDelete );
@@ -2208,52 +2245,6 @@ public void clusterStateProcessed(String source, ClusterState oldState, ClusterS
22082245 }, "delete snapshot [" + repository + "]" + Arrays .toString (snapshotNames ), listener ::onFailure );
22092246 }
22102247
2211- private static List <SnapshotId > matchingSnapshotIds (
2212- List <SnapshotId > inProgress ,
2213- RepositoryData repositoryData ,
2214- String [] snapshotsOrPatterns ,
2215- String repositoryName
2216- ) {
2217- final Map <String , SnapshotId > allSnapshotIds = repositoryData .getSnapshotIds ()
2218- .stream ()
2219- .collect (Collectors .toMap (SnapshotId ::getName , Function .identity ()));
2220- final Set <SnapshotId > foundSnapshots = new HashSet <>(inProgress );
2221- for (String snapshotOrPattern : snapshotsOrPatterns ) {
2222- if (Regex .isSimpleMatchPattern (snapshotOrPattern )) {
2223- for (Map .Entry <String , SnapshotId > entry : allSnapshotIds .entrySet ()) {
2224- if (Regex .simpleMatch (snapshotOrPattern , entry .getKey ())) {
2225- foundSnapshots .add (entry .getValue ());
2226- }
2227- }
2228- } else {
2229- final SnapshotId foundId = allSnapshotIds .get (snapshotOrPattern );
2230- if (foundId == null ) {
2231- if (inProgress .stream ().noneMatch (snapshotId -> snapshotId .getName ().equals (snapshotOrPattern ))) {
2232- throw new SnapshotMissingException (repositoryName , snapshotOrPattern );
2233- }
2234- } else {
2235- foundSnapshots .add (allSnapshotIds .get (snapshotOrPattern ));
2236- }
2237- }
2238- }
2239- return List .copyOf (foundSnapshots );
2240- }
2241-
2242- // Return in-progress snapshot entries by name and repository in the given cluster state or null if none is found
2243- private static List <SnapshotsInProgress .Entry > findInProgressSnapshots (
2244- SnapshotsInProgress snapshots ,
2245- String [] snapshotNames ,
2246- String repositoryName
2247- ) {
2248- List <SnapshotsInProgress .Entry > entries = new ArrayList <>();
2249- for (SnapshotsInProgress .Entry entry : snapshots .entries ()) {
2250- if (entry .repository ().equals (repositoryName ) && Regex .simpleMatch (snapshotNames , entry .snapshot ().getSnapshotId ().getName ())) {
2251- entries .add (entry );
2252- }
2253- }
2254- return entries ;
2255- }
2256-
22572248 /**
22582249 * Checks if the given {@link SnapshotsInProgress.Entry} is currently writing to the repository.
22592250 *
0 commit comments