Skip to content

Commit e4c96c9

Browse files
committed
fix: return all available branches regardless their datasets
1 parent 63ebfd0 commit e4c96c9

File tree

6 files changed

+91
-16
lines changed

6 files changed

+91
-16
lines changed

engine/internal/provision/mode_local_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,10 @@ func (m mockFSManager) ListBranches() (map[string]string, error) {
134134
return nil, nil
135135
}
136136

137+
func (m mockFSManager) ListAllBranches() (map[string]string, error) {
138+
return nil, nil
139+
}
140+
137141
func (m mockFSManager) AddBranchProp(_, _ string) error {
138142
return nil
139143
}
@@ -154,6 +158,10 @@ func (m mockFSManager) GetRepo() (*models.Repo, error) {
154158
return nil, nil
155159
}
156160

161+
func (m mockFSManager) GetAllRepo() (*models.Repo, error) {
162+
return nil, nil
163+
}
164+
157165
func (m mockFSManager) SetDSA(_, _ string) error {
158166
return nil
159167
}

engine/internal/provision/pool/manager.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ type Branching interface {
5757
VerifyBranchMetadata() error
5858
CreateBranch(branchName, snapshotID string) error
5959
ListBranches() (map[string]string, error)
60+
ListAllBranches() (map[string]string, error)
6061
GetRepo() (*models.Repo, error)
62+
GetAllRepo() (*models.Repo, error)
6163
SetRelation(parent, snapshotName string) error
6264
Snapshot(snapshotName string) error
6365
SetMountpoint(path, branch string) error

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ func (m *LVManager) ListBranches() (map[string]string, error) {
184184
return nil, nil
185185
}
186186

187+
// ListAllBranches lists all branches.
188+
func (m *LVManager) ListAllBranches() (map[string]string, error) {
189+
log.Msg("ListAllBranches is not supported for LVM. Skip the operation")
190+
191+
return nil, nil
192+
}
193+
187194
// AddBranchProp adds branch to snapshot property.
188195
func (m *LVManager) AddBranchProp(_, _ string) error {
189196
log.Msg("AddBranchProp is not supported for LVM. Skip the operation")
@@ -233,6 +240,13 @@ func (m *LVManager) GetRepo() (*models.Repo, error) {
233240
return nil, nil
234241
}
235242

243+
// GetAllRepo provides data repository details.
244+
func (m *LVManager) GetAllRepo() (*models.Repo, error) {
245+
log.Msg("GetAllRepo is not supported for LVM. Skip the operation")
246+
247+
return nil, nil
248+
}
249+
236250
// SetDSA sets value of DataStateAt to snapshot.
237251
func (m *LVManager) SetDSA(_, _ string) error {
238252
log.Msg("SetDSA is not supported for LVM. Skip the operation")

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

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ const (
2626
empty = "-"
2727
)
2828

29+
type cmdCfg struct {
30+
pool string
31+
}
32+
2933
// InitBranching inits data branching.
3034
func (m *Manager) InitBranching() error {
3135
snapshots := m.SnapshotList()
@@ -206,10 +210,28 @@ func (m *Manager) SetMountpoint(path, name string) error {
206210

207211
// ListBranches lists data pool branches.
208212
func (m *Manager) ListBranches() (map[string]string, error) {
213+
return m.listBranches(cmdCfg{pool: m.config.Pool.Name})
214+
}
215+
216+
// ListAllBranches lists all branches.
217+
func (m *Manager) ListAllBranches() (map[string]string, error) {
218+
return m.listBranches(cmdCfg{})
219+
}
220+
221+
func (m *Manager) listBranches(cfg cmdCfg) (map[string]string, error) {
222+
filter := ""
223+
args := []any{branchProp}
224+
225+
if cfg.pool != "" {
226+
filter = "-r %s"
227+
228+
args = append(args, cfg.pool)
229+
}
230+
209231
cmd := fmt.Sprintf(
210232
// Get ZFS snapshots (-t) with options (-o) without output headers (-H) filtered by pool (-r).
211233
// Excluding snapshots without "dle:branch" property ("grep -v").
212-
`zfs list -H -t snapshot -o %s,name -r %s | grep -v "^-" | cat`, branchProp, m.config.Pool.Name,
234+
`zfs list -H -t snapshot -o %s,name `+filter+` | grep -v "^-" | cat`, args...,
213235
)
214236

215237
out, err := m.runner.Run(cmd)
@@ -229,13 +251,15 @@ func (m *Manager) ListBranches() (map[string]string, error) {
229251
continue
230252
}
231253

254+
dataset, _, _ := strings.Cut(fields[1], "@")
255+
232256
if !strings.Contains(fields[0], branchSep) {
233-
branches[fields[0]] = fields[1]
257+
branches[models.BranchName(dataset, fields[0])] = fields[1]
234258
continue
235259
}
236260

237261
for _, branchName := range strings.Split(fields[0], branchSep) {
238-
branches[branchName] = fields[1]
262+
branches[models.BranchName(dataset, branchName)] = fields[1]
239263
}
240264
}
241265

@@ -244,16 +268,30 @@ func (m *Manager) ListBranches() (map[string]string, error) {
244268

245269
var repoFields = []any{"name", parentProp, childProp, branchProp, rootProp, dataStateAtLabel, messageProp}
246270

247-
// GetRepo provides repository details about snapshots and branches.
271+
// GetRepo provides repository details about snapshots and branches filtered by data pool.
248272
func (m *Manager) GetRepo() (*models.Repo, error) {
273+
return m.getRepo(cmdCfg{pool: m.config.Pool.Name})
274+
}
275+
276+
// GetAllRepo provides all repository details about snapshots and branches.
277+
func (m *Manager) GetAllRepo() (*models.Repo, error) {
278+
return m.getRepo(cmdCfg{})
279+
}
280+
281+
func (m *Manager) getRepo(cmdCfg cmdCfg) (*models.Repo, error) {
249282
strFields := bytes.TrimRight(bytes.Repeat([]byte(`%s,`), len(repoFields)), ",")
250283

251-
cmd := fmt.Sprintf(
252-
// Get ZFS snapshots (-t) with options (-o) without output headers (-H) filtered by pool (-r).
253-
`zfs list -H -t snapshot -o `+string(strFields)+" -r %s", append(repoFields, m.config.Pool.Name)...,
254-
)
284+
// Get ZFS snapshots (-t) with options (-o) without output headers (-H) filtered by pool (-r).
285+
format := `zfs list -H -t snapshot -o ` + string(strFields)
286+
args := repoFields
255287

256-
out, err := m.runner.Run(cmd)
288+
if cmdCfg.pool != "" {
289+
format += " -r %s"
290+
291+
args = append(args, cmdCfg.pool)
292+
}
293+
294+
out, err := m.runner.Run(fmt.Sprintf(format, args...))
257295
if err != nil {
258296
return nil, fmt.Errorf("failed to list branches: %w. Out: %v", err, out)
259297
}
@@ -271,6 +309,8 @@ func (m *Manager) GetRepo() (*models.Repo, error) {
271309
continue
272310
}
273311

312+
dataset, _, _ := strings.Cut(fields[0], "@")
313+
274314
snDetail := models.SnapshotDetails{
275315
ID: fields[0],
276316
Parent: fields[1],
@@ -279,6 +319,7 @@ func (m *Manager) GetRepo() (*models.Repo, error) {
279319
Root: unwindField(fields[4]),
280320
DataStateAt: strings.Trim(fields[5], empty),
281321
Message: decodeCommitMessage(fields[6]),
322+
Dataset: dataset,
282323
}
283324

284325
repo.Snapshots[fields[0]] = snDetail
@@ -288,7 +329,7 @@ func (m *Manager) GetRepo() (*models.Repo, error) {
288329
continue
289330
}
290331

291-
repo.Branches[sn] = fields[0]
332+
repo.Branches[models.BranchName(dataset, sn)] = fields[0]
292333
}
293334
}
294335

engine/internal/srv/branch.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ func (s *Server) listBranches(w http.ResponseWriter, r *http.Request) {
2626
return
2727
}
2828

29-
branches, err := fsm.ListBranches()
29+
branches, err := fsm.ListAllBranches()
3030
if err != nil {
3131
api.SendBadRequestError(w, r, err.Error())
3232
return
3333
}
3434

35-
repo, err := fsm.GetRepo()
35+
repo, err := fsm.GetAllRepo()
3636
if err != nil {
3737
api.SendBadRequestError(w, r, err.Error())
3838
return
@@ -46,12 +46,15 @@ func (s *Server) listBranches(w http.ResponseWriter, r *http.Request) {
4646
continue
4747
}
4848

49+
_, branchNam, _ := strings.Cut(branchName, "_")
50+
4951
branchDetails = append(branchDetails,
5052
models.BranchView{
51-
Name: branchName,
52-
Parent: findBranchParent(repo.Snapshots, snapshotDetails.ID, branchName),
53+
Name: branchNam,
54+
Parent: findBranchParent(repo.Snapshots, snapshotDetails.ID, branchNam),
5355
DataStateAt: snapshotDetails.DataStateAt,
5456
SnapshotID: snapshotDetails.ID,
57+
Dataset: snapshotDetails.Dataset,
5558
})
5659
}
5760

@@ -343,7 +346,7 @@ func (s *Server) log(w http.ResponseWriter, r *http.Request) {
343346
return
344347
}
345348

346-
snapshotID, ok := repo.Branches[logRequest.BranchName]
349+
snapshotID, ok := repo.Branches[models.BranchName(fsm.Pool().Name, logRequest.BranchName)]
347350
if !ok {
348351
api.SendBadRequestError(w, r, "branch not found: "+logRequest.BranchName)
349352
return
@@ -389,7 +392,7 @@ func (s *Server) deleteBranch(w http.ResponseWriter, r *http.Request) {
389392
return
390393
}
391394

392-
snapshotID, ok := repo.Branches[deleteRequest.BranchName]
395+
snapshotID, ok := repo.Branches[models.BranchName(fsm.Pool().Name, deleteRequest.BranchName)]
393396
if !ok {
394397
api.SendBadRequestError(w, r, "branch not found: "+deleteRequest.BranchName)
395398
return

engine/pkg/models/branch.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type SnapshotDetails struct {
2828
Root []string `json:"root"`
2929
DataStateAt string `json:"dataStateAt"`
3030
Message string `json:"message"`
31+
Dataset string `json:"dataset"`
3132
}
3233

3334
// BranchView describes branch view.
@@ -36,4 +37,10 @@ type BranchView struct {
3637
Parent string `json:"parent"`
3738
DataStateAt string `json:"dataStateAt"`
3839
SnapshotID string `json:"snapshotID"`
40+
Dataset string `json:"dataset"`
41+
}
42+
43+
// BranchName returns full branch name.
44+
func BranchName(pool, branch string) string {
45+
return pool + "_" + branch
3946
}

0 commit comments

Comments
 (0)