more performant proccess for removing all snapshots on a dataset
Signed-off-by: Travis Glenn Hansen <travisghansen@yahoo.com>
This commit is contained in:
		
							parent
							
								
									1a5b2e699a
								
							
						
					
					
						commit
						023f7e16b2
					
				|  | @ -1601,29 +1601,10 @@ class FreeNASApiDriver extends CsiBaseDriver { | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async removeSnapshotsFromDatatset(datasetName, options = {}) { |   async removeSnapshotsFromDatatset(datasetName) { | ||||||
|     // TODO: alter the logic here to not be n+1
 |  | ||||||
|     // https://jira.ixsystems.com/browse/NAS-111708
 |  | ||||||
|     const httpClient = await this.getHttpClient(); |  | ||||||
|     const httpApiClient = await this.getTrueNASHttpApiClient(); |     const httpApiClient = await this.getTrueNASHttpApiClient(); | ||||||
| 
 |     let job_id = await httpApiClient.DatasetDestroySnapshots(datasetName); | ||||||
|     let response; |     await httpApiClient.CoreWaitForJob(job_id, 30); | ||||||
|     let endpoint = `/pool/dataset/id/${encodeURIComponent(datasetName)}`; |  | ||||||
|     response = await httpClient.get(endpoint, { "extra.snapshots": 1 }); |  | ||||||
| 
 |  | ||||||
|     //console.log(response);
 |  | ||||||
| 
 |  | ||||||
|     if (response.statusCode == 404) { |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|     if (response.statusCode == 200) { |  | ||||||
|       for (let snapshot of response.body.snapshots) { |  | ||||||
|         await httpApiClient.SnapshotDelete(snapshot.name); |  | ||||||
|       } |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     throw new Error("unhandled statusCode: " + response.statusCode); |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
|  | @ -2224,9 +2205,7 @@ class FreeNASApiDriver extends CsiBaseDriver { | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             // remove snapshots from target
 |             // remove snapshots from target
 | ||||||
|             await this.removeSnapshotsFromDatatset(datasetName, { |             await this.removeSnapshotsFromDatatset(datasetName); | ||||||
|               force: true, |  | ||||||
|             }); |  | ||||||
|           } else { |           } else { | ||||||
|             try { |             try { | ||||||
|               response = await httpApiClient.CloneCreate( |               response = await httpApiClient.CloneCreate( | ||||||
|  | @ -2377,9 +2356,7 @@ class FreeNASApiDriver extends CsiBaseDriver { | ||||||
|             ); |             ); | ||||||
| 
 | 
 | ||||||
|             // remove snapshots from target
 |             // remove snapshots from target
 | ||||||
|             await this.removeSnapshotsFromDatatset(datasetName, { |             await this.removeSnapshotsFromDatatset(datasetName); | ||||||
|               force: true, |  | ||||||
|             }); |  | ||||||
| 
 | 
 | ||||||
|             // remove snapshot from source
 |             // remove snapshot from source
 | ||||||
|             await httpApiClient.SnapshotDelete(fullSnapshotName, { |             await httpApiClient.SnapshotDelete(fullSnapshotName, { | ||||||
|  | @ -2707,7 +2684,6 @@ class FreeNASApiDriver extends CsiBaseDriver { | ||||||
|    * @param {*} call |    * @param {*} call | ||||||
|    */ |    */ | ||||||
|   async ControllerExpandVolume(call) { |   async ControllerExpandVolume(call) { | ||||||
|     // TODO: https://jira.ixsystems.com/browse/NAS-111707
 |  | ||||||
|     const driver = this; |     const driver = this; | ||||||
|     const driverZfsResourceType = this.getDriverZfsResourceType(); |     const driverZfsResourceType = this.getDriverZfsResourceType(); | ||||||
|     const httpApiClient = await this.getTrueNASHttpApiClient(); |     const httpApiClient = await this.getTrueNASHttpApiClient(); | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | const { sleep } = require("../../../utils/general"); | ||||||
| const { Zetabyte } = require("../../../utils/zfs"); | const { Zetabyte } = require("../../../utils/zfs"); | ||||||
| 
 | 
 | ||||||
| // used for in-memory cache of the version info
 | // used for in-memory cache of the version info
 | ||||||
|  | @ -491,6 +492,30 @@ class Api { | ||||||
|     throw new Error(JSON.stringify(response.body)); |     throw new Error(JSON.stringify(response.body)); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   async DatasetDestroySnapshots(datasetName, data = {}) { | ||||||
|  |     const httpClient = await this.getHttpClient(false); | ||||||
|  |     let response; | ||||||
|  |     let endpoint; | ||||||
|  | 
 | ||||||
|  |     data.name = datasetName; | ||||||
|  | 
 | ||||||
|  |     endpoint = "/pool/dataset/destroy_snapshots"; | ||||||
|  |     response = await httpClient.post(endpoint, data); | ||||||
|  | 
 | ||||||
|  |     if (response.statusCode == 200) { | ||||||
|  |       return response.body; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if ( | ||||||
|  |       response.statusCode == 422 && | ||||||
|  |       JSON.stringify(response.body).includes("already exists") | ||||||
|  |     ) { | ||||||
|  |       return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     throw new Error(JSON.stringify(response.body)); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   async SnapshotSet(snapshotName, properties) { |   async SnapshotSet(snapshotName, properties) { | ||||||
|     const httpClient = await this.getHttpClient(false); |     const httpClient = await this.getHttpClient(false); | ||||||
|     let response; |     let response; | ||||||
|  | @ -654,6 +679,31 @@ class Api { | ||||||
|     throw new Error(JSON.stringify(response.body)); |     throw new Error(JSON.stringify(response.body)); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   async CoreWaitForJob(job_id, timeout = 0) { | ||||||
|  |     if (!job_id) { | ||||||
|  |       throw new Error("invalid job_id"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const startTime = Date.now() / 1000; | ||||||
|  |     let currentTime; | ||||||
|  | 
 | ||||||
|  |     let job; | ||||||
|  | 
 | ||||||
|  |     // wait for job to finish
 | ||||||
|  |     while (!job || !["SUCCESS", "ABORTED", "FAILED"].includes(job.state)) { | ||||||
|  |       job = await this.CoreGetJobs({ id: job_id }); | ||||||
|  |       job = job[0]; | ||||||
|  |       await sleep(3000); | ||||||
|  | 
 | ||||||
|  |       currentTime = Date.now() / 1000; | ||||||
|  |       if (timeout > 0 && currentTime > startTime + timeout) { | ||||||
|  |         throw new Error("timeout waiting for job to complete"); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return job; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   async CoreGetJobs(data) { |   async CoreGetJobs(data) { | ||||||
|     const httpClient = await this.getHttpClient(false); |     const httpClient = await this.getHttpClient(false); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue