Skip to content

Commit dc32f5b

Browse files
committed
Merge branch '382-snapshot-list-workaround' into 'master'
fix: keep the snapshot list with relevant values (#382) Closes #382 See merge request postgres-ai/database-lab!539
2 parents 94ac19a + 5d1cff9 commit dc32f5b

File tree

6 files changed

+93
-25
lines changed

6 files changed

+93
-25
lines changed

engine/internal/provision/pool/manager.go

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,12 @@ func NewManager(runner runners.Runner, config ManagerConfig) (FSManager, error)
6969

7070
switch config.Pool.Mode {
7171
case zfs.PoolMode:
72-
osUser, err := user.Current()
72+
zfsConfig, err := buildZFSConfig(config)
7373
if err != nil {
74-
return nil, errors.Wrap(err, "failed to get current user")
74+
return nil, err
7575
}
7676

77-
manager = zfs.NewFSManager(runner, zfs.Config{
78-
Pool: config.Pool,
79-
PreSnapshotSuffix: config.PreSnapshotSuffix,
80-
OSUsername: osUser.Username,
81-
})
77+
manager = zfs.NewFSManager(runner, zfsConfig)
8278

8379
case lvm.PoolMode:
8480
if manager, err = lvm.NewFSManager(runner, config.Pool); err != nil {
@@ -93,3 +89,41 @@ func NewManager(runner runners.Runner, config ManagerConfig) (FSManager, error)
9389

9490
return manager, nil
9591
}
92+
93+
// BuildFromExistingManager prepares FSManager from an existing one.
94+
func BuildFromExistingManager(fsm FSManager, config ManagerConfig) (FSManager, error) {
95+
switch manager := fsm.(type) {
96+
case *zfs.Manager:
97+
zfsConfig, err := buildZFSConfig(config)
98+
if err != nil {
99+
return nil, err
100+
}
101+
102+
manager.UpdateConfig(zfsConfig)
103+
104+
fsm = manager
105+
106+
case *lvm.LVManager:
107+
manager.UpdateConfig(config.Pool)
108+
109+
fsm = manager
110+
111+
default:
112+
return nil, fmt.Errorf(`unsupported thin-clone manager: %T`, manager)
113+
}
114+
115+
return fsm, nil
116+
}
117+
118+
func buildZFSConfig(config ManagerConfig) (zfs.Config, error) {
119+
osUser, err := user.Current()
120+
if err != nil {
121+
return zfs.Config{}, fmt.Errorf("failed to get current user: %w", err)
122+
}
123+
124+
return zfs.Config{
125+
Pool: config.Pool,
126+
PreSnapshotSuffix: config.PreSnapshotSuffix,
127+
OSUsername: osUser.Username,
128+
}, nil
129+
}

engine/internal/provision/pool/pool_manager.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,10 @@ func (pm *Manager) examineEntries(entries []os.DirEntry) (map[string]FSManager,
259259

260260
poolMappings := make(map[string]string)
261261

262+
pm.mu.Lock()
263+
originalPools := pm.fsManagerPool
264+
pm.mu.Unlock()
265+
262266
for _, entry := range entries {
263267
if !entry.IsDir() {
264268
continue
@@ -324,10 +328,19 @@ func (pm *Manager) examineEntries(entries []os.DirEntry) (map[string]FSManager,
324328
}
325329
}
326330

327-
fsm, err := NewManager(pm.runner, ManagerConfig{
331+
var fsm FSManager
332+
333+
managerConfig := ManagerConfig{
328334
Pool: pool,
329335
PreSnapshotSuffix: pm.cfg.PreSnapshotSuffix,
330-
})
336+
}
337+
338+
if originalFSM, ok := originalPools[pool.Name]; ok {
339+
fsm, err = BuildFromExistingManager(originalFSM, managerConfig)
340+
} else {
341+
fsm, err = NewManager(pm.runner, managerConfig)
342+
}
343+
331344
if err != nil {
332345
log.Msg("failed to create clone manager:", err.Error())
333346
continue

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ func (m *LVManager) Pool() *resources.Pool {
4747
return m.pool
4848
}
4949

50+
// UpdateConfig updates the manager's pool.
51+
func (m *LVManager) UpdateConfig(pool *resources.Pool) {
52+
m.pool = pool
53+
}
54+
5055
// CreateClone creates a new volume.
5156
func (m *LVManager) CreateClone(name, _ string) error {
5257
return CreateVolume(m.runner, m.volumeGroup, m.logicalVolume, name, m.pool.ClonesDir())

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

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,10 @@ type Config struct {
159159
// NewFSManager creates a new Manager instance for ZFS.
160160
func NewFSManager(runner runners.Runner, config Config) *Manager {
161161
m := Manager{
162-
runner: runner,
163-
config: config,
164-
mu: &sync.Mutex{},
162+
runner: runner,
163+
config: config,
164+
mu: &sync.Mutex{},
165+
snapshots: make([]resources.Snapshot, 0),
165166
}
166167

167168
return &m
@@ -172,6 +173,11 @@ func (m *Manager) Pool() *resources.Pool {
172173
return m.config.Pool
173174
}
174175

176+
// UpdateConfig updates the manager's configuration.
177+
func (m *Manager) UpdateConfig(cfg Config) {
178+
m.config = cfg
179+
}
180+
175181
// CreateClone creates a new ZFS clone.
176182
func (m *Manager) CreateClone(cloneName, snapshotID string) error {
177183
exists, err := m.cloneExists(cloneName)
@@ -316,14 +322,20 @@ func (m *Manager) CreateSnapshot(poolSuffix, dataStateAt string) (string, error)
316322
return "", fmt.Errorf("failed to parse dataStateAt: %w", err)
317323
}
318324

319-
m.addSnapshotToList(resources.Snapshot{
325+
newSnapshot := resources.Snapshot{
320326
ID: snapshotName,
321327
CreatedAt: time.Now(),
322328
DataStateAt: dataStateTime,
323329
Pool: m.config.Pool.Name,
324-
})
330+
}
331+
332+
if !strings.HasSuffix(snapshotName, m.config.PreSnapshotSuffix) {
333+
m.addSnapshotToList(newSnapshot)
325334

326-
go m.RefreshSnapshotList()
335+
log.Dbg("New snapshot:", newSnapshot)
336+
337+
m.RefreshSnapshotList()
338+
}
327339

328340
return snapshotName, nil
329341
}
@@ -511,8 +523,11 @@ func (m *Manager) GetFilesystemState() (models.FileSystem, error) {
511523

512524
// SnapshotList returns a list of snapshots.
513525
func (m *Manager) SnapshotList() []resources.Snapshot {
514-
snapshotList := m.snapshots
515-
return snapshotList
526+
m.mu.Lock()
527+
snapshots := m.snapshots
528+
m.mu.Unlock()
529+
530+
return snapshots
516531
}
517532

518533
// RefreshSnapshotList updates the list of snapshots.
@@ -559,20 +574,22 @@ func (m *Manager) getSnapshots() ([]resources.Snapshot, error) {
559574

560575
func (m *Manager) addSnapshotToList(snapshot resources.Snapshot) {
561576
m.mu.Lock()
562-
m.snapshots = append(m.snapshots, snapshot)
577+
m.snapshots = append([]resources.Snapshot{snapshot}, m.snapshots...)
563578
m.mu.Unlock()
564579
}
565580

566581
func (m *Manager) removeSnapshotFromList(snapshotName string) {
582+
m.mu.Lock()
583+
567584
for i, snapshot := range m.snapshots {
568585
if snapshot.ID == snapshotName {
569-
m.mu.Lock()
570-
m.snapshots = append(m.snapshots[:i], m.snapshots[i+1:]...)
571-
m.mu.Unlock()
586+
m.snapshots = append((m.snapshots)[:i], (m.snapshots)[i+1:]...)
572587

573588
break
574589
}
575590
}
591+
592+
m.mu.Unlock()
576593
}
577594

578595
// ListFilesystems lists ZFS file systems (clones, pools).

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ func TestBuildingCommands(t *testing.T) {
199199

200200
func TestSnapshotList(t *testing.T) {
201201
t.Run("Snapshot list", func(t *testing.T) {
202-
fsManager := NewFSManager(runnerMock{}, Config{})
202+
fsManager := NewFSManager(runnerMock{}, Config{Pool: &resources.Pool{Name: "testPool"}})
203203

204204
require.Equal(t, 0, len(fsManager.SnapshotList()))
205205

@@ -216,11 +216,11 @@ func TestSnapshotList(t *testing.T) {
216216
fsManager.addSnapshotToList(snapshot3)
217217

218218
require.Equal(t, 3, len(fsManager.SnapshotList()))
219-
require.Equal(t, []resources.Snapshot{{ID: "test1"}, {ID: "test2"}, {ID: "test3"}}, fsManager.SnapshotList())
219+
require.Equal(t, []resources.Snapshot{{ID: "test3"}, {ID: "test2"}, {ID: "test1"}}, fsManager.SnapshotList())
220220

221221
fsManager.removeSnapshotFromList("test2")
222222

223223
require.Equal(t, 2, len(fsManager.SnapshotList()))
224-
require.Equal(t, []resources.Snapshot{{ID: "test1"}, {ID: "test3"}}, fsManager.SnapshotList())
224+
require.Equal(t, []resources.Snapshot{{ID: "test3"}, {ID: "test1"}}, fsManager.SnapshotList())
225225
})
226226
}

engine/internal/retrieval/engine/postgres/snapshot/physical.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,6 @@ func (p *PhysicalInitial) parseWAL(ctx context.Context, containerID string, pgVe
703703
Cmd: []string{"sh", "-c", cmd},
704704
})
705705
if err != nil {
706-
log.Dbg("failed to parse WAL: ", err)
707706
return ""
708707
}
709708

0 commit comments

Comments
 (0)