File: builder.go

package info (click to toggle)
golang-github-protonmail-gluon 0.17.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 16,020 kB
  • sloc: sh: 55; makefile: 5
file content (126 lines) | stat: -rw-r--r-- 3,677 bytes parent folder | download
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
}