1351
Cargo.lock
generated
1351
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,19 @@ serde_json = "1.0.148"
|
|||||||
sha2 = "0.10.9"
|
sha2 = "0.10.9"
|
||||||
tokio-util = "0.7.18"
|
tokio-util = "0.7.18"
|
||||||
|
|
||||||
|
sqlx = { version = "0.8.6", optional = true, features = [
|
||||||
|
"chrono",
|
||||||
|
"json",
|
||||||
|
"postgres",
|
||||||
|
"runtime-tokio",
|
||||||
|
"uuid",
|
||||||
|
] }
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
insta = "1.46.0"
|
insta = "1.46.0"
|
||||||
tracing-test = { version = "0.2.5", features = ["no-env-filter"] }
|
tracing-test = { version = "0.2.5", features = ["no-env-filter"] }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
postgres = ["dep:sqlx"]
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
-- Add migration script here
|
||||||
@@ -10,6 +10,9 @@ use crate::{
|
|||||||
|
|
||||||
pub mod in_process;
|
pub mod in_process;
|
||||||
|
|
||||||
|
#[cfg(feature = "postgres")]
|
||||||
|
pub mod postgres;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BackingStore<T: Specification, TStore: BackingStoreEdge<T>> {
|
pub struct BackingStore<T: Specification, TStore: BackingStoreEdge<T>> {
|
||||||
inner: TStore,
|
inner: TStore,
|
||||||
@@ -42,6 +45,16 @@ impl<T: Specification> BackingStore<T, BackingStoreInProcess<T>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "postgres")]
|
||||||
|
impl<T: Specification> BackingStore<T, postgres::BackingStorePostgres<T>> {
|
||||||
|
pub fn postgres(database_url: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: postgres::BackingStorePostgres::new(database_url),
|
||||||
|
_marker: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait BackingStoreEdge<T: Specification>: Send + Sync + Clone {
|
pub trait BackingStoreEdge<T: Specification>: Send + Sync + Clone {
|
||||||
fn get_owned_and_potential_leases(
|
fn get_owned_and_potential_leases(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
72
crates/nocontrol/src/control_plane/backing_store/postgres.rs
Normal file
72
crates/nocontrol/src/control_plane/backing_store/postgres.rs
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use anyhow::Context;
|
||||||
|
use sqlx::PgPool;
|
||||||
|
|
||||||
|
use crate::{Specification, stores::BackingStoreEdge};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct BackingStorePostgres<T: Specification> {
|
||||||
|
pool: PgPool,
|
||||||
|
_marker: PhantomData<T>,
|
||||||
|
}
|
||||||
|
impl<T: Specification> BackingStorePostgres<T> {
|
||||||
|
pub(crate) async fn new(database_url: &str) -> anyhow::Result<Self> {
|
||||||
|
let pool = sqlx::PgPool::connect(database_url)
|
||||||
|
.await
|
||||||
|
.context("failed to connect to database")?;
|
||||||
|
|
||||||
|
sqlx::migrate!("migrations/postgres/")
|
||||||
|
.run(&pool)
|
||||||
|
.await
|
||||||
|
.context("failed to migrate")?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
_marker: PhantomData,
|
||||||
|
pool,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Specification> BackingStoreEdge<T> for BackingStorePostgres<T> {
|
||||||
|
async fn get_owned_and_potential_leases(
|
||||||
|
&self,
|
||||||
|
worker_id: &uuid::Uuid,
|
||||||
|
) -> anyhow::Result<Vec<crate::manifests::ManifestState<T>>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_manifests(&self) -> anyhow::Result<Vec<crate::manifests::ManifestState<T>>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get(&self, name: &str) -> anyhow::Result<Option<crate::manifests::ManifestState<T>>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update_lease(
|
||||||
|
&self,
|
||||||
|
manifest_state: &crate::manifests::ManifestState<T>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn acquire_lease(
|
||||||
|
&self,
|
||||||
|
manifest_state: &crate::manifests::ManifestState<T>,
|
||||||
|
worker_id: &crate::manifests::WorkerId,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn upsert_manifest(&self, manifest: crate::manifests::Manifest<T>) -> anyhow::Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update_state(
|
||||||
|
&self,
|
||||||
|
manifest: &crate::manifests::ManifestState<T>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
12
mise.toml
12
mise.toml
@@ -8,3 +8,15 @@ run = "cargo nextest run"
|
|||||||
[tasks.example]
|
[tasks.example]
|
||||||
alias = "e"
|
alias = "e"
|
||||||
run = "cargo run --bin kubernetes-like"
|
run = "cargo run --bin kubernetes-like"
|
||||||
|
|
||||||
|
[tasks."example:postgres"]
|
||||||
|
run = "cargo run --bin postgres-backed"
|
||||||
|
|
||||||
|
[tasks."local:up"]
|
||||||
|
run = "docker compose -f ./templates/docker/docker-compose.yml up -d --remove-orphans --wait"
|
||||||
|
|
||||||
|
[tasks."local:down"]
|
||||||
|
run = "docker compose -f ./templates/docker/docker-compose.yml down"
|
||||||
|
|
||||||
|
[tasks."local:logs"]
|
||||||
|
run = "docker compose -f ./templates/docker/docker-compose.yml logs -f --tail=500"
|
||||||
|
|||||||
20
templates/docker/docker-compose.yml
Normal file
20
templates/docker/docker-compose.yml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:18
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: devuser
|
||||||
|
POSTGRES_PASSWORD: devpassword
|
||||||
|
POSTGRES_DB: dev
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U devuser -d dev"]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
volumes:
|
||||||
|
- ${PWD}/fs/volumes/postgres/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
|
||||||
|
command:
|
||||||
|
- "postgres"
|
||||||
|
- "-c"
|
||||||
|
- "wal_level=logical" #required for MaterializedPostgreSQL
|
||||||
Reference in New Issue
Block a user