Pinecone standalone refactoring
This refactors the `dendrite-demo-pinecone` executable so that it:
1. Converts the old `.key` file into a standard `.pem` file
2. Allows passing in the `--config` option to supply a normal Dendrite configuration file, so that you can configure PostgreSQL instead of SQLite, appservices and all the other usual stuff
MODIFY
cmd/dendrite-demo-pinecone/main.go
cmd/dendrite-demo-pinecone/main.go
@@ -24,6 +24,7 @@ import (
"net"
"net/http"
"os"
+ "strings"
"time"
"github.com/gorilla/mux"
@@ -42,6 +43,7 @@ import (
"github.com/matrix-org/dendrite/setup"
"github.com/matrix-org/dendrite/setup/base"
"github.com/matrix-org/dendrite/setup/config"
+ "github.com/matrix-org/dendrite/test"
"github.com/matrix-org/dendrite/userapi"
"github.com/matrix-org/gomatrixserverlib"
@@ -70,31 +72,84 @@ func main() {
var pk ed25519.PublicKey
var sk ed25519.PrivateKey
- keyfile := *instanceName + ".key"
+ // iterate through the cli args and check if the config flag was set
+ configFlagSet := false
+ for _, arg := range os.Args {
+ if arg == "--config" || arg == "-config" {
+ configFlagSet = true
+ break
+ }
+ }
+
+ cfg := &config.Dendrite{}
+
+ // use custom config if config flag is set
+ if configFlagSet {
+ cfg = setup.ParseFlags(true)
+ sk = cfg.Global.PrivateKey
+ } else {
+ keyfile := *instanceName + ".pem"
if _, err := os.Stat(keyfile); os.IsNotExist(err) {
- if pk, sk, err = ed25519.GenerateKey(nil); err != nil {
- panic(err)
+ oldkeyfile := *instanceName + ".key"
+ if _, err = os.Stat(oldkeyfile); os.IsNotExist(err) {
+ if err = test.NewMatrixKey(keyfile); err != nil {
+ panic("failed to generate a new PEM key: " + err.Error())
}
- if err = os.WriteFile(keyfile, sk, 0644); err != nil {
- panic(err)
+ if _, sk, err = config.LoadMatrixKey(keyfile, os.ReadFile); err != nil {
+ panic("failed to load PEM key: " + err.Error())
}
- } else if err == nil {
- if sk, err = os.ReadFile(keyfile); err != nil {
- panic(err)
+ } else {
+ if sk, err = os.ReadFile(oldkeyfile); err != nil {
+ panic("failed to read the old private key: " + err.Error())
}
if len(sk) != ed25519.PrivateKeySize {
panic("the private key is not long enough")
}
- pk = sk.Public().(ed25519.PublicKey)
+ if err := test.SaveMatrixKey(keyfile, sk); err != nil {
+ panic("failed to convert the private key to PEM format: " + err.Error())
+ }
+ }
+ } else {
+ var err error
+ if _, sk, err = config.LoadMatrixKey(keyfile, os.ReadFile); err != nil {
+ panic("failed to load PEM key: " + err.Error())
+ }
+ }
+ cfg.Defaults(true)
+ cfg.Global.PrivateKey = sk
+ cfg.Global.JetStream.StoragePath = config.Path(fmt.Sprintf("%s/", *instanceName))
+ cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-account.db", *instanceName))
+ cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-mediaapi.db", *instanceName))
+ cfg.SyncAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-syncapi.db", *instanceName))
+ cfg.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-roomserver.db", *instanceName))
+ cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-keyserver.db", *instanceName))
+ cfg.FederationAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-federationapi.db", *instanceName))
+ cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName))
+ cfg.MSCs.MSCs = []string{"msc2836", "msc2946"}
+ cfg.MSCs.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-mscs.db", *instanceName))
+ cfg.ClientAPI.RegistrationDisabled = false
+ cfg.ClientAPI.OpenRegistrationWithoutVerificationEnabled = true
+ if err := cfg.Derive(); err != nil {
+ panic(err)
+ }
}
+ pk = sk.Public().(ed25519.PublicKey)
+ cfg.Global.ServerName = gomatrixserverlib.ServerName(hex.EncodeToString(pk))
+ cfg.Global.KeyID = gomatrixserverlib.KeyID(signing.KeyID)
+
+ base := base.NewBaseDendrite(cfg, "Monolith")
+ defer base.Close() // nolint: errcheck
+
pRouter := pineconeRouter.NewRouter(logrus.WithField("pinecone", "router"), sk, false)
pQUIC := pineconeSessions.NewSessions(logrus.WithField("pinecone", "sessions"), pRouter, []string{"matrix"})
pMulticast := pineconeMulticast.NewMulticast(logrus.WithField("pinecone", "multicast"), pRouter)
pManager := pineconeConnections.NewConnectionManager(pRouter, nil)
pMulticast.Start()
if instancePeer != nil && *instancePeer != "" {
- pManager.AddPeer(*instancePeer)
+ for _, peer := range strings.Split(*instancePeer, ",") {
+ pManager.AddPeer(strings.Trim(peer, " \t\r\n"))
+ }
}
go func() {
@@ -125,29 +180,6 @@ func main() {
}
}()
- cfg := &config.Dendrite{}
- cfg.Defaults(true)
- cfg.Global.ServerName = gomatrixserverlib.ServerName(hex.EncodeToString(pk))
- cfg.Global.PrivateKey = sk
- cfg.Global.KeyID = gomatrixserverlib.KeyID(signing.KeyID)
- cfg.Global.JetStream.StoragePath = config.Path(fmt.Sprintf("%s/", *instanceName))
- cfg.UserAPI.AccountDatabase.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-account.db", *instanceName))
- cfg.MediaAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-mediaapi.db", *instanceName))
- cfg.SyncAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-syncapi.db", *instanceName))
- cfg.RoomServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-roomserver.db", *instanceName))
- cfg.KeyServer.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-keyserver.db", *instanceName))
- cfg.FederationAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-federationapi.db", *instanceName))
- cfg.AppServiceAPI.Database.ConnectionString = config.DataSource(fmt.Sprintf("file:%s-appservice.db", *instanceName))
- cfg.MSCs.MSCs = []string{"msc2836", "msc2946"}
- cfg.ClientAPI.RegistrationDisabled = false
- cfg.ClientAPI.OpenRegistrationWithoutVerificationEnabled = true
- if err := cfg.Derive(); err != nil {
- panic(err)
- }
-
- base := base.NewBaseDendrite(cfg, "Monolith")
- defer base.Close() // nolint: errcheck
-
federation := conn.CreateFederationClient(base, pQUIC)
serverKeyAPI := &signing.YggdrasilKeys{}

MODIFY
setup/config/config.go
setup/config/config.go
@@ -224,12 +224,7 @@ func loadConfig(
}
privateKeyPath := absPath(basePath, c.Global.PrivateKeyPath)
- privateKeyData, err := readFile(privateKeyPath)
- if err != nil {
- return nil, err
- }
-
- if c.Global.KeyID, c.Global.PrivateKey, err = readKeyPEM(privateKeyPath, privateKeyData, true); err != nil {
+ if c.Global.KeyID, c.Global.PrivateKey, err = LoadMatrixKey(privateKeyPath, readFile); err != nil {
return nil, err
}
@@ -265,6 +260,14 @@ func loadConfig(
return &c, nil
}
+func LoadMatrixKey(privateKeyPath string, readFile func(string) ([]byte, error)) (gomatrixserverlib.KeyID, ed25519.PrivateKey, error) {
+ privateKeyData, err := readFile(privateKeyPath)
+ if err != nil {
+ return "", nil, err
+ }
+ return readKeyPEM(privateKeyPath, privateKeyData, true)
+}
+
// Derive generates data that is derived from various values provided in
// the config file.
func (config *Dendrite) Derive() error {

MODIFY
test/keys.go
test/keys.go
package test
import (
+ "crypto/ed25519"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
@@ -44,6 +45,10 @@ func NewMatrixKey(matrixKeyPath string) (err error) {
if err != nil {
return err
}
+ return SaveMatrixKey(matrixKeyPath, data[3:])
+}
+
+func SaveMatrixKey(matrixKeyPath string, data ed25519.PrivateKey) error {
keyOut, err := os.OpenFile(matrixKeyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return err
@@ -62,7 +67,7 @@ func NewMatrixKey(matrixKeyPath string) (err error) {
Headers: map[string]string{
"Key-ID": fmt.Sprintf("ed25519:%s", keyID[:6]),
},
- Bytes: data[3:],
+ Bytes: data,
})
return err
}

Pinecone standalone refactoring (#2685)

This refactors the `dendrite-demo-pinecone` executable so that it:

1. Converts the old `.key` file into a standard `.pem` file
2. Allows passing in the `--config` option to supply a normal Dendrite configuration file, so that you can configure PostgreSQL instead of SQLite, appservices and all the other usual stuff