@@ -229,6 +229,14 @@ func (s *Server) deleteSnapshot(w http.ResponseWriter, r *http.Request) {
229229 return
230230 }
231231
232+ // Prevent deletion of the last snapshot in the pool.
233+ snapshotCnt := len (fsm .SnapshotList ())
234+
235+ if fullDataset , _ , found := strings .Cut (snapshotID , "@" ); found && fullDataset == poolName && snapshotCnt == 1 {
236+ api .SendBadRequestError (w , r , "cannot destroy the last snapshot in the pool" )
237+ return
238+ }
239+
232240 // Check if snapshot exists.
233241 if _ , err := fsm .GetSnapshotProperties (snapshotID ); err != nil {
234242 if runnerError , ok := err .(runners.RunnerError ); ok {
@@ -322,7 +330,7 @@ func (s *Server) deleteSnapshot(w http.ResponseWriter, r *http.Request) {
322330
323331 if snapshotProperties .Clones == "" && snapshot .NumClones == 0 {
324332 // Destroy dataset if there are no related objects
325- if fullDataset , _ , found := strings .Cut (snapshotID , "@" ); found {
333+ if fullDataset , _ , found := strings .Cut (snapshotID , "@" ); found && fullDataset != poolName {
326334 if err = fsm .DestroyDataset (fullDataset ); err != nil {
327335 api .SendBadRequestError (w , r , err .Error ())
328336 return
@@ -504,6 +512,19 @@ func (s *Server) createClone(w http.ResponseWriter, r *http.Request) {
504512 }
505513
506514 cloneRequest .Snapshot = & types.SnapshotCloneFieldRequest {ID : snapshotID }
515+ } else {
516+ cloneRequest .Branch = branching .DefaultBranch
517+ }
518+
519+ if cloneRequest .ID != "" {
520+ fsm , err := s .getFSManagerForBranch (cloneRequest .Branch )
521+ if err != nil {
522+ api .SendBadRequestError (w , r , err .Error ())
523+ return
524+ }
525+
526+ // Check if there is any clone revision under the dataset.
527+ cloneRequest .Revision = findMaxCloneRevision (fsm .Pool ().CloneRevisionLocation (cloneRequest .Branch , cloneRequest .ID ))
507528 }
508529
509530 newClone , err := s .Cloning .CreateClone (cloneRequest )
@@ -533,6 +554,39 @@ func (s *Server) createClone(w http.ResponseWriter, r *http.Request) {
533554 log .Dbg (fmt .Sprintf ("Clone ID=%s is being created" , newClone .ID ))
534555}
535556
557+ func findMaxCloneRevision (path string ) int {
558+ files , err := os .ReadDir (path )
559+ if err != nil {
560+ log .Err (err )
561+ return 0
562+ }
563+
564+ maxIndex := - 1
565+
566+ for _ , file := range files {
567+ if ! file .IsDir () {
568+ continue
569+ }
570+
571+ revisionIndex , ok := strings .CutPrefix (file .Name (), "r" )
572+ if ! ok {
573+ continue
574+ }
575+
576+ index , err := strconv .Atoi (revisionIndex )
577+ if err != nil {
578+ log .Err (err )
579+ continue
580+ }
581+
582+ if index > maxIndex {
583+ maxIndex = index
584+ }
585+ }
586+
587+ return maxIndex + 1
588+ }
589+
536590func (s * Server ) destroyClone (w http.ResponseWriter , r * http.Request ) {
537591 cloneID := mux .Vars (r )["id" ]
538592
0 commit comments