Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Postgres as a persistence backend #8202

Merged
merged 1 commit into from
Jun 28, 2024

Conversation

etorreborre
Copy link
Member

@etorreborre etorreborre commented Jun 21, 2024

This PR adds the possibility to use Postgres as a backend to persist data for an Ockam node.

In order to use a Postgres database simply set the following environment variables:

  • OCKAM_POSTGRES_HOST: for example localhost
  • OCKAM_POSTGRES_PORT: for example 5432
  • OCKAM_POSTGRES_DATABASE_NAME (optional): for example postgres
  • OCKAM_POSTGRES_USER (optional): for example admin
  • OCKAM_POSTGRES_PASSWORD (optional): for example password

Implementation notes

This PR touches a large number of files and the following sections will help the reviewer understanding the changes.

Driver

The sqlx library provides an Any driver, which replaces the SQLite driver used before this PR.
With the Any driver and its associated types, AnyConnection, AnyPool, Type<Any> etc... we can open a connection to either a SQLite or a Postgres database by specifying the proper URL:

  • sqlite:file:in-memory?mode=memory&cache=shared for an in-memory SQLite database
  • sqlite:file://my-file?mode=rwc for an on-disk SQLite database
  • postgres://admin:password@localhost:5432/postgres for a Postgres database

This logic is encapsulated in a new DatabaseConfiguration type.

The result of this driver change is that a number of method signatures had to be changed from ... SQLite ... to ... Any ....

Queries

Some queries had to be changed in order to work with both databases.

In particular the queries of the form INSERT OR REPLACE don't work with Postgres. Those queries have been replaced with INSERT ... ON CONFLICT ... DO UPDATE | NOTHING.

Data types serialization

The mapping of Rust types to database types is quite different between SQLite and Postgres.
To support this properly:

The ToSqlxType typeclass has been removed in favor of using the Encode and Type typeclasses from sqlx directly. While this typeclass was useful when using SQLite only, it became a source of encoding bugs with both Postgres and SQLite.

Reading boolean and optional values from the database was not working out of the box. This was fixed via:

Tests

Repositories

All the repositories code is now tested with 3 databases: SQLite in-memory, SQLite on-disk and Postgres (if available in the environment). This test support is provided by the sqlx_database::with_dbs function.

Execution

Note that you need to run the tests sequentially if you run them with a local Postgres database since it will be shared between all tests. For example:

cargo --locked nextest --config-file ./tools/nextest/.config/nextest.toml run --no-fail-fast --test-threads 1

Clean-up

For the same reason, some system tests are now calling TestNode::clean() in order to make sure that the database is cleaned-up before the test runs.

CI

I have added a CI job to run all the nextest test suite with a Postgres database. That job only selects test names containing sql, to cover all the repositories, and cli_state to test the high-level behavior which generally involves some persistence.

Vaults

The modeling for vaults has changed slightly. An enum has been introduced to represent exactly a vault metadata:

pub enum VaultType {
    DatabaseVault {
        use_aws_kms: UseAwsKms,
    },
    LocalFileVault {
        path: PathBuf,
        use_aws_kms: UseAwsKms,
    },
}

A vault is either stored directly in the database, with some dedicated tables, or in a file (using SQLite).
The naming of is_kms has been changed to use_aws_kms to indicate that:

  • If the Vault uses a KMS it is specifically an AWS one
  • Not all of the Vault data is stored in the KMS. Some data is still stored locally, only the signing keys are stored in the KMS.
  • I have also made some change to the output of ockam vault list/show to better reflect the vault types:
❯ ockam vault list
   │ Name: default
   │ Type: Internal

   │ Name: v1
   │ Type: External
   │ Path: /Users/etorreborre/.ockam-4/vault-v1

   │ Name: v2
   │ Type: External
   │ Path: /Users/etorreborre/.ockam-4/second-vault

   │ Name: v3
   │ Type: External
   │ Path: /Users/etorreborre/.ockam-4/vault-v3
   │ Uses AWS KMS: true
  • The JSON output of the ockam vault show command also changes. This is not necessarily the best JSON output but I didn't try to improve it for now.

@etorreborre etorreborre self-assigned this Jun 21, 2024
@etorreborre etorreborre force-pushed the etorreborre/feat/sqlx-any-remove-sqlx-type branch 23 times, most recently from d5ae7af to 78fffa8 Compare June 26, 2024 13:10
@etorreborre etorreborre marked this pull request as ready for review June 26, 2024 13:43
@etorreborre etorreborre requested a review from a team as a code owner June 26, 2024 13:43
@SanjoDeundiak
Copy link
Member

Nice!

Copy link
Member

@adrianbenavides adrianbenavides left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome! I pray to the gods that we never have to support oracle 😄

@etorreborre etorreborre force-pushed the etorreborre/feat/sqlx-any-remove-sqlx-type branch from c23fd8b to 1c4cfc0 Compare June 28, 2024 09:42
SanjoDeundiak
SanjoDeundiak previously approved these changes Jun 28, 2024
@etorreborre etorreborre force-pushed the etorreborre/feat/sqlx-any-remove-sqlx-type branch from a7a17bd to 859e94d Compare June 28, 2024 13:22
@etorreborre etorreborre force-pushed the etorreborre/feat/sqlx-any-remove-sqlx-type branch from 859e94d to 4e2ed06 Compare June 28, 2024 13:54
@etorreborre etorreborre added this pull request to the merge queue Jun 28, 2024
Merged via the queue into develop with commit 8c91653 Jun 28, 2024
43 checks passed
@etorreborre etorreborre deleted the etorreborre/feat/sqlx-any-remove-sqlx-type branch June 28, 2024 14:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants