Skip to content

Commit c7e8a9a

Browse files
committed
Merge branch '574-branch-list' into 'dle-4-0'
fix: the main branch issues (#574) See merge request postgres-ai/database-lab!932
2 parents 8897a48 + a432f43 commit c7e8a9a

File tree

5 files changed

+84
-21
lines changed

5 files changed

+84
-21
lines changed

engine/internal/provision/mode_local_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ func (m mockFSManager) CreateBranch(_, _ string) error {
126126
return nil
127127
}
128128

129+
func (m mockFSManager) DestroyBranch(_ string) error {
130+
return nil
131+
}
132+
129133
func (m mockFSManager) Snapshot(_ string) error {
130134
return nil
131135
}

engine/internal/provision/pool/manager.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type Branching interface {
5757
VerifyBranchMetadata() error
5858
CreateDataset(datasetName string) error
5959
CreateBranch(branchName, snapshotID string) error
60+
DestroyBranch(branchName string) (err error)
6061
ListBranches() (map[string]string, error)
6162
ListAllBranches() ([]models.BranchEntity, error)
6263
GetRepo() (*models.Repo, error)

engine/internal/provision/thinclones/lvm/lvmanager.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,13 @@ func (m *LVManager) CreateBranch(_, _ string) error {
170170
return nil
171171
}
172172

173+
// DestroyBranch destroys branch.
174+
func (m *LVManager) DestroyBranch(_ string) error {
175+
log.Msg("DestroyBranch is not supported for LVM. Skip the operation")
176+
177+
return nil
178+
}
179+
173180
// Snapshot takes a snapshot of the current data state.
174181
func (m *LVManager) Snapshot(_ string) error {
175182
log.Msg("Snapshot is not supported for LVM. Skip the operation")

engine/internal/provision/thinclones/zfs/zfs.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,17 @@ func (m *Manager) DestroySnapshot(snapshotName string) error {
389389
return nil
390390
}
391391

392+
// DestroyBranch destroys the branch with all dependent commits.
393+
func (m *Manager) DestroyBranch(branchName string) error {
394+
cmd := fmt.Sprintf("zfs destroy -R %s", branchName)
395+
396+
if _, err := m.runner.Run(cmd); err != nil {
397+
return fmt.Errorf("failed to run command: %w", err)
398+
}
399+
400+
return nil
401+
}
402+
392403
type snapshotRelation struct {
393404
parent string
394405
branch string

engine/internal/srv/branch.go

Lines changed: 61 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,33 @@ func (s *Server) listBranches(w http.ResponseWriter, r *http.Request) {
4545

4646
branchDetails := make([]models.BranchView, 0, len(branches))
4747

48+
// branchRegistry is used to display the "main" branch with only the most recent snapshot.
49+
branchRegistry := make(map[string]int, 0)
50+
4851
for _, branchEntity := range branches {
4952
snapshotDetails, ok := repo.Snapshots[branchEntity.SnapshotID]
5053
if !ok {
5154
continue
5255
}
5356

54-
branchDetails = append(branchDetails,
55-
models.BranchView{
56-
Name: branchEntity.Name,
57-
Parent: findBranchParent(repo.Snapshots, snapshotDetails.ID, branchEntity.Name),
58-
DataStateAt: snapshotDetails.DataStateAt,
59-
SnapshotID: snapshotDetails.ID,
60-
Dataset: snapshotDetails.Dataset,
61-
})
57+
branchView := models.BranchView{
58+
Name: branchEntity.Name,
59+
Parent: findBranchParent(repo.Snapshots, snapshotDetails.ID, branchEntity.Name),
60+
DataStateAt: snapshotDetails.DataStateAt,
61+
SnapshotID: snapshotDetails.ID,
62+
Dataset: snapshotDetails.Dataset,
63+
}
64+
65+
if position, ok := branchRegistry[branchEntity.Name]; ok {
66+
if branchView.DataStateAt > branchDetails[position].DataStateAt {
67+
branchDetails[position] = branchView
68+
}
69+
70+
continue
71+
}
72+
73+
branchRegistry[branchView.Name] = len(branchDetails)
74+
branchDetails = append(branchDetails, branchView)
6275
}
6376

6477
if err := api.WriteJSON(w, http.StatusOK, branchDetails); err != nil {
@@ -209,7 +222,12 @@ func (s *Server) createBranch(w http.ResponseWriter, r *http.Request) {
209222
return
210223
}
211224

212-
if err := fsm.SetRoot(createRequest.BranchName, branchSnapshot); err != nil {
225+
if err := fsm.SetRoot(createRequest.BranchName, snapshotID); err != nil {
226+
api.SendBadRequestError(w, r, err.Error())
227+
return
228+
}
229+
230+
if err := fsm.SetRelation(snapshotID, branchSnapshot); err != nil {
213231
api.SendBadRequestError(w, r, err.Error())
214232
return
215233
}
@@ -360,6 +378,7 @@ func (s *Server) snapshot(w http.ResponseWriter, r *http.Request) {
360378
}
361379

362380
targetBranchSnap := fmt.Sprintf("%[1]s@%[1]s", dataStateAt)
381+
363382
targetSnap := fmt.Sprintf("%s/%s", fsm.Pool().BranchName(clone.Snapshot.Pool, clone.Branch), targetBranchSnap)
364383

365384
if err := fsm.Move(currentSnapshotID, snapshotName, targetSnap); err != nil {
@@ -560,26 +579,47 @@ func (s *Server) deleteBranch(w http.ResponseWriter, r *http.Request) {
560579

561580
toRemove := snapshotsToRemove(repo, snapshotID, deleteRequest.BranchName)
562581

563-
// Pre-check.
564-
for _, snapshotID := range toRemove {
565-
if cloneNum := s.Cloning.GetCloneNumber(snapshotID); cloneNum > 0 {
566-
log.Warn(fmt.Sprintf("cannot delete branch %q because snapshot %q contains %d clone(s)",
567-
deleteRequest.BranchName, snapshotID, cloneNum))
582+
if len(toRemove) > 0 {
583+
// Pre-check.
584+
preCheckList := make(map[string]int)
585+
586+
for _, snapshotID := range toRemove {
587+
if cloneNum := s.Cloning.GetCloneNumber(snapshotID); cloneNum > 0 {
588+
preCheckList[snapshotID] = cloneNum
589+
}
568590
}
569-
}
570591

571-
for _, snapshotID := range toRemove {
572-
if err := fsm.DestroySnapshot(snapshotID); err != nil {
573-
log.Warn(fmt.Sprintf("failed to remove snapshot %q:", snapshotID), err.Error())
592+
if len(preCheckList) > 0 {
593+
errMsg := fmt.Sprintf("cannot delete branch %q because", deleteRequest.BranchName)
594+
595+
for snapID, cloneNum := range preCheckList {
596+
errMsg += fmt.Sprintf(" snapshot %q contains %d clone(s)", snapID, cloneNum)
597+
}
598+
599+
log.Warn(errMsg)
600+
api.SendBadRequestError(w, r, errMsg)
601+
602+
return
603+
}
604+
605+
brName := fsm.Pool().BranchName(fsm.Pool().Name, deleteRequest.BranchName)
606+
607+
if err := fsm.DestroyBranch(brName); err != nil {
608+
log.Warn(fmt.Sprintf("failed to remove snapshot %q:", brName), err)
609+
api.SendBadRequestError(w, r, fmt.Sprintf("failed to remove snapshot %q:", brName))
610+
611+
return
574612
}
575-
}
576613

577-
if len(toRemove) > 0 {
578614
datasetFull := strings.Split(toRemove[0], "@")
579615
datasetName, _ := strings.CutPrefix(datasetFull[0], fsm.Pool().Name+"/")
580616

581617
if err := fsm.DestroyClone(datasetName); err != nil {
582-
log.Warn("cannot destroy the underlying branch dataset", err)
618+
errMsg := fmt.Sprintf("cannot destroy the underlying branch dataset: %s", datasetName)
619+
log.Warn(errMsg, err)
620+
api.SendBadRequestError(w, r, errMsg)
621+
622+
return
583623
}
584624
}
585625

0 commit comments

Comments
 (0)