1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
package gluon
import (
"crypto/tls"
"io"
"os"
"time"
"github.com/ProtonMail/gluon/async"
"github.com/ProtonMail/gluon/db"
"github.com/ProtonMail/gluon/imap"
"github.com/ProtonMail/gluon/internal/backend"
"github.com/ProtonMail/gluon/internal/db_impl/sqlite3"
"github.com/ProtonMail/gluon/internal/session"
"github.com/ProtonMail/gluon/limits"
"github.com/ProtonMail/gluon/profiling"
"github.com/ProtonMail/gluon/reporter"
"github.com/ProtonMail/gluon/store"
"github.com/ProtonMail/gluon/version"
"github.com/sirupsen/logrus"
)
type serverBuilder struct {
dataDir string
databaseDir string
delim string
loginJailTime time.Duration
tlsConfig *tls.Config
idleBulkTime time.Duration
inLogger io.Writer
outLogger io.Writer
versionInfo version.Info
cmdExecProfBuilder profiling.CmdProfilerBuilder
storeBuilder store.Builder
reporter reporter.Reporter
disableParallelism bool
imapLimits limits.IMAP
uidValidityGenerator imap.UIDValidityGenerator
panicHandler async.PanicHandler
dbCI db.ClientInterface
}
func newBuilder() (*serverBuilder, error) {
return &serverBuilder{
delim: "/",
cmdExecProfBuilder: &profiling.NullCmdExecProfilerBuilder{},
storeBuilder: &store.OnDiskStoreBuilder{},
reporter: &reporter.NullReporter{},
idleBulkTime: 500 * time.Millisecond,
imapLimits: limits.DefaultLimits(),
uidValidityGenerator: imap.DefaultEpochUIDValidityGenerator(),
panicHandler: async.NoopPanicHandler{},
dbCI: sqlite3.NewBuilder(),
}, nil
}
func (builder *serverBuilder) build() (*Server, error) {
if builder.dataDir == "" {
dir, err := os.MkdirTemp("", "gluon-*")
if err != nil {
return nil, err
}
builder.dataDir = dir
}
if err := os.MkdirAll(builder.dataDir, 0o700); err != nil {
return nil, err
}
if builder.databaseDir == "" {
dir, err := os.MkdirTemp("", "gluon-*")
if err != nil {
return nil, err
}
builder.databaseDir = dir
}
if err := os.MkdirAll(builder.databaseDir, 0o700); err != nil {
return nil, err
}
backend, err := backend.New(
builder.dataDir,
builder.databaseDir,
builder.storeBuilder,
builder.delim,
builder.loginJailTime,
builder.imapLimits,
builder.panicHandler,
builder.dbCI,
)
if err != nil {
return nil, err
}
// Defer delete all the previous databases from removed user accounts. This is required since we can't
// close ent databases on demand.
if err := db.DeleteDeferredDBFiles(builder.databaseDir); err != nil {
logrus.WithError(err).Error("Failed to remove old database files")
}
s := &Server{
dataDir: builder.dataDir,
databaseDir: builder.databaseDir,
backend: backend,
sessions: make(map[int]*session.Session),
serveErrCh: async.NewQueuedChannel[error](1, 1, builder.panicHandler),
serveDoneCh: make(chan struct{}),
serveWG: async.MakeWaitGroup(builder.panicHandler),
inLogger: builder.inLogger,
outLogger: builder.outLogger,
tlsConfig: builder.tlsConfig,
idleBulkTime: builder.idleBulkTime,
storeBuilder: builder.storeBuilder,
cmdExecProfBuilder: builder.cmdExecProfBuilder,
versionInfo: builder.versionInfo,
reporter: builder.reporter,
disableParallelism: builder.disableParallelism,
uidValidityGenerator: builder.uidValidityGenerator,
panicHandler: builder.panicHandler,
}
return s, nil
}
|