Convert from BoltDB to Maildir storage for emails

This commit is contained in:
2018-06-26 03:08:51 +01:00
parent d25ed6c1bd
commit a3c2508160
19 changed files with 869 additions and 175 deletions

View File

@@ -9,19 +9,20 @@ import (
"gopkg.in/urfave/cli.v1"
"ur.gs/crockery/internal/imap"
"ur.gs/crockery/internal/store"
)
func crockeryInit(c *cli.Context) error {
db := c.GlobalString("db")
home := c.GlobalString("home")
domain := c.String("domain")
certFile := c.String("cert")
keyFile := c.String("key")
postmasterPassword := c.String("postmaster-password")
if db == "" {
return fmt.Errorf("No crockery database file specified")
db := store.BuildDatabasePath(home)
if home == "" {
return fmt.Errorf("No crockery home directory specified")
}
if domain == "" {
@@ -42,8 +43,13 @@ func crockeryInit(c *cli.Context) error {
return fmt.Errorf("A password must be specified for the postmaster user")
}
// TODO: check it is a directory
if _, err := os.Stat(home); os.IsNotExist(err) {
return fmt.Errorf("Home directory %q does not exist!", home)
}
if _, err := os.Stat(db); !os.IsNotExist(err) {
return fmt.Errorf("File %q already exists, refusing to overwrite", db)
return fmt.Errorf("Database file %q already exists!", db)
}
certPEM, err := ioutil.ReadFile(certFile)
@@ -56,11 +62,11 @@ func crockeryInit(c *cli.Context) error {
return fmt.Errorf("Failed to read key from %q: %v", keyFile, err)
}
if err := store.Init(db, domain, certPEM, keyPEM); err != nil {
return fmt.Errorf("Couldn't initialize datase %q: %v", db, err)
if err := store.Init(home, domain, certPEM, keyPEM); err != nil {
return fmt.Errorf("Couldn't initialize home directory %q: %v", home, err)
}
datastore, err := store.New(context.Background(), db)
datastore, err := store.New(context.Background(), home)
if err != nil {
return err
}
@@ -71,27 +77,27 @@ func crockeryInit(c *cli.Context) error {
}
username := "postmaster@" + domain
mailbox := store.Mailbox{
Account: username,
Name: imap.InboxName,
}
if err := datastore.CreateMailbox(&mailbox); err != nil {
return fmt.Errorf("Failed to create admin mailbox %s: %v", mailbox.Name, err)
}
postmaster := store.Account{
Username: username,
Admin: true,
PasswordHash: hash,
DefaultMailbox: mailbox.ID, // Automatically filled in by the store
Username: username,
Admin: true,
PasswordHash: hash,
}
if err := datastore.CreateAccount(&postmaster); err != nil {
return fmt.Errorf("Failed to create admin account %s: %v", postmaster.Username, err)
}
log.Printf("Created %q for domain %q. Next step:\n\t%s -db %s run", db, domain, os.Args[0], db)
maildir := store.Maildir{Account: postmaster, Name: ""}
if err := datastore.CreateMaildir(&maildir); err != nil {
return fmt.Errorf("Failed to create admin maildir %q: %v", maildir.Rel(), err)
}
log.Printf(
"Initialized %q for domain %q. Next step:\n\t%s -home %q run",
home, domain, os.Args[0], home,
)
return nil
}

View File

@@ -14,16 +14,16 @@ import (
)
func crockeryRun(c *cli.Context) error {
db := c.GlobalString("db")
home := c.GlobalString("home")
ctx, cancel := context.WithCancel(context.Background())
if db == "" {
return fmt.Errorf("No crockery database file specified")
if home == "" {
return fmt.Errorf("No crockery home directory specified")
}
log.Printf("Loading config from file %q", db)
log.Printf("Loading config from directory %q", home)
datastore, err := store.New(context.Background(), db)
datastore, err := store.New(context.Background(), home)
if err != nil {
return err
}
@@ -31,7 +31,7 @@ func crockeryRun(c *cli.Context) error {
defer datastore.Close()
if datastore.Domain() == "" {
return fmt.Errorf("No domain configured in file %q", db)
return fmt.Errorf("No domain configured for Crockery home directory %q", home)
}
if _, err := datastore.FindAccount("postmaster@" + datastore.Domain()); err != nil {

View File

@@ -18,10 +18,10 @@ func main() {
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "db",
Usage: "Database file to use",
EnvVar: "CROCKERY_DB",
Value: "crockery.db",
Name: "home",
Usage: "Home directory to use",
EnvVar: "HOME",
Value: os.Getenv("HOME"),
},
}