Skip to content

Commit b280437

Browse files
committed
cli: start/stop storage modules in ctl commands
Start LifetimeModule instances when running CLI subcommands that operate on storage/auth DBs, and stop them on Close(). This fixes imap-acct crashes due to uninitialized imapsql backends while preserving ManageableStorage support.
1 parent 1e5e01e commit b280437

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

internal/cli/ctl/moduleinit.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,36 @@ func closeIfNeeded(i interface{}) {
3737
}
3838
}
3939

40+
type managedStorage struct {
41+
module.ManageableStorage
42+
started bool
43+
}
44+
45+
func (m *managedStorage) Close() error {
46+
if !m.started {
47+
return nil
48+
}
49+
if lm, ok := m.ManageableStorage.(module.LifetimeModule); ok {
50+
return lm.Stop()
51+
}
52+
return nil
53+
}
54+
55+
type managedUserDB struct {
56+
module.PlainUserDB
57+
started bool
58+
}
59+
60+
func (m *managedUserDB) Close() error {
61+
if !m.started {
62+
return nil
63+
}
64+
if lm, ok := m.PlainUserDB.(module.LifetimeModule); ok {
65+
return lm.Stop()
66+
}
67+
return nil
68+
}
69+
4070
func getCfgBlockModule(ctx *cli.Context) (*container.C, module.Module, error) {
4171
cfgPath := ctx.String("config")
4272
if cfgPath == "" {
@@ -92,6 +122,14 @@ func openStorage(ctx *cli.Context) (module.Storage, error) {
92122
return nil, cli.Exit(fmt.Sprintf("Error: configuration block %s is not an IMAP storage", ctx.String("cfg-block")), 2)
93123
}
94124

125+
started := false
126+
if lt, ok := storage.(module.LifetimeModule); ok {
127+
if err := lt.Start(); err != nil {
128+
return nil, err
129+
}
130+
started = true
131+
}
132+
95133
if updStore, ok := mod.(updatepipe.Backend); ok {
96134
if err := updStore.EnableUpdatePipe(updatepipe.ModePush); err != nil && !errors.Is(err, os.ErrNotExist) {
97135
fmt.Fprintf(os.Stderr, "Failed to initialize update pipe, do not remove messages from mailboxes open by clients: %v\n", err)
@@ -100,6 +138,11 @@ func openStorage(ctx *cli.Context) (module.Storage, error) {
100138
fmt.Fprintf(os.Stderr, "No update pipe support, do not remove messages from mailboxes open by clients\n")
101139
}
102140

141+
if started {
142+
if ms, ok := storage.(module.ManageableStorage); ok {
143+
return &managedStorage{ManageableStorage: ms, started: started}, nil
144+
}
145+
}
103146
return storage, nil
104147
}
105148

@@ -114,5 +157,16 @@ func openUserDB(ctx *cli.Context) (module.PlainUserDB, error) {
114157
return nil, cli.Exit(fmt.Sprintf("Error: configuration block %s is not a local credentials store", ctx.String("cfg-block")), 2)
115158
}
116159

160+
started := false
161+
if lt, ok := userDB.(module.LifetimeModule); ok {
162+
if err := lt.Start(); err != nil {
163+
return nil, err
164+
}
165+
started = true
166+
}
167+
168+
if started {
169+
return &managedUserDB{PlainUserDB: userDB, started: started}, nil
170+
}
117171
return userDB, nil
118172
}

0 commit comments

Comments
 (0)