Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion databases.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
{
"name": "Test database 2 - MariaDB",
"database": "mariadb",
"type": "mysql",
"type": "mariadb",
"username": "mariadb",
"password": "changeme",
"port": 3306,
Expand Down Expand Up @@ -81,6 +81,16 @@
"username": "default",
"host": "db-valkey-auth",
"generated_id": "16678561-ff7e-4c97-8c83-0adeff214681"
},
{
"name": "Test database 12 - Mysql",
"database": "mysqldb",
"type": "mysql",
"username": "mysqldb",
"password": "changeme",
"port": 3306,
"host": "db-mysql",
"generated_id": "16656124-ff7e-4c97-8c83-0adeff214681"
}
]
}
177 changes: 96 additions & 81 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ services:
# - ./databases.toml:/config/config.toml
- cargo-registry:/usr/local/cargo/registry
- cargo-git:/usr/local/cargo/git
- /var/run/docker.sock:/var/run/docker.sock

# - /var/run/docker.sock:/var/run/docker.sock
# - cargo-target:/app/target
# - sqlite-data:/sqlite-data/workspace/data
# - ./scripts/sqlite/test-db:/sqlite-data-2/workspace/data
Expand All @@ -28,35 +27,50 @@ services:
networks:
- portabase

db-postgres:
container_name: db-postgres
image: postgres:17-alpine
# db-postgres:
# container_name: db-postgres
# image: postgres:17-alpine
# ports:
# - "5436:5432"
# volumes:
# - postgres-data:/var/lib/postgresql/data
# environment:
# - POSTGRES_DB=devdb
# - POSTGRES_USER=devuser
# - POSTGRES_PASSWORD=changeme
# networks:
# - portabase

db-mariadb:
container_name: db-mariadb
image: mariadb:latest
ports:
- "5436:5432"
- "3311:3306"
environment:
- MYSQL_DATABASE=mariadb
- MYSQL_USER=mariadb
- MYSQL_PASSWORD=changeme
- MYSQL_RANDOM_ROOT_PASSWORD=yes
volumes:
- postgres-data:/var/lib/postgresql/data
- mariadb-data:/var/lib/mysql
networks:
- portabase

db-mysql:
container_name: db-mysql
image: mysql:9.5
ports:
- "3312:3306"
environment:
- POSTGRES_DB=devdb
- POSTGRES_USER=devuser
- POSTGRES_PASSWORD=changeme
- MYSQL_DATABASE=mysqldb
- MYSQL_USER=mysqldb
- MYSQL_PASSWORD=changeme
- MYSQL_RANDOM_ROOT_PASSWORD=yes
volumes:
- mysql-data:/var/lib/mysql
networks:
- portabase
#
# db-mariadb:
# container_name: db-mariadb
# image: mariadb:latest
# ports:
# - "3311:3306"
# environment:
# - MYSQL_DATABASE=mariadb
# - MYSQL_USER=mariadb
# - MYSQL_PASSWORD=changeme
# - MYSQL_RANDOM_ROOT_PASSWORD=yes
# volumes:
# - mariadb-data:/var/lib/mysql
# networks:
# - portabase
#
#
# db-mongodb-auth:
# container_name: db-mongodb-auth
Expand Down Expand Up @@ -105,67 +119,68 @@ services:
# stdin_open: true
# tty: true

db-redis:
image: redis:latest
container_name: db-redis
ports:
- "6379:6379"
volumes:
- redis-data:/data
command: [ "redis-server", "--appendonly", "yes" ]
networks:
- portabase

db-redis-auth:
image: redis:latest
container_name: db-redis-auth
ports:
- "6380:6379"
volumes:
- redis-data-auth:/data
environment:
- REDIS_PASSWORD=supersecurepassword
command: [ "redis-server", "--requirepass", "supersecurepassword", "--appendonly", "yes" ]
networks:
- portabase

db-valkey:
image: valkey/valkey
container_name: db-valkey
environment:
- ALLOW_EMPTY_PASSWORD=yes
ports:
- '6381:6379'
volumes:
- valkey-data:/data
networks:
- portabase

db-valkey-auth:
image: valkey/valkey
container_name: db-valkey-auth
command: >
--requirepass "supersecurepassword"
ports:
- '6382:6379'
volumes:
- valkey-data-auth:/data
networks:
- portabase
# db-redis:
# image: redis:latest
# container_name: db-redis
# ports:
# - "6379:6379"
# volumes:
# - redis-data:/data
# command: [ "redis-server", "--appendonly", "yes" ]
# networks:
# - portabase
#
# db-redis-auth:
# image: redis:latest
# container_name: db-redis-auth
# ports:
# - "6380:6379"
# volumes:
# - redis-data-auth:/data
# environment:
# - REDIS_PASSWORD=supersecurepassword
# command: [ "redis-server", "--requirepass", "supersecurepassword", "--appendonly", "yes" ]
# networks:
# - portabase
#
# db-valkey:
# image: valkey/valkey
# container_name: db-valkey
# environment:
# - ALLOW_EMPTY_PASSWORD=yes
# ports:
# - '6381:6379'
# volumes:
# - valkey-data:/data
# networks:
# - portabase
#
# db-valkey-auth:
# image: valkey/valkey
# container_name: db-valkey-auth
# command: >
# --requirepass "supersecurepassword"
# ports:
# - '6382:6379'
# volumes:
# - valkey-data-auth:/data
# networks:
# - portabase

volumes:
cargo-registry:
cargo-git:
# cargo-target:
postgres-data:
# mariadb-data:
# mongodb-data:
# mongodb-data-auth:
# sqlite-data:
redis-data:
redis-data-auth:
valkey-data:
valkey-data-auth:
# postgres-data:
mariadb-data:
mysql-data:
# mongodb-data:
# mongodb-data-auth:
# sqlite-data:
# redis-data:
# redis-data-auth:
# valkey-data:
# valkey-data-auth:

networks:
portabase:
Expand Down
1 change: 1 addition & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ RUN if [ "$TARGETARCH" = "amd64" ]; then \
rm -rf /tmp/pg-x64 /tmp/pg-arm && \
chmod +x /usr/lib/postgresql/*/bin/*


# =========================
# MongoDB client binaries
# =========================
Expand Down
5 changes: 3 additions & 2 deletions src/domain/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::services::config::{DatabaseConfig, DbType};
use anyhow::Result;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use crate::domain::mariadb::database::MariaDBDatabase;

#[async_trait::async_trait]
pub trait Database: Send + Sync {
Expand All @@ -28,7 +29,7 @@ impl DatabaseFactory {
Arc::new(PostgresDatabase::new(cfg, format))
}
DbType::Mysql => Arc::new(MySQLDatabase::new(cfg)),
DbType::Mariadb => Arc::new(MySQLDatabase::new(cfg)),
DbType::Mariadb => Arc::new(MariaDBDatabase::new(cfg)),
DbType::MongoDB => Arc::new(MongoDatabase::new(cfg)),
DbType::Sqlite => Arc::new(SqliteDatabase::new(cfg)),
DbType::Redis => Arc::new(RedisDatabase::new(cfg)),
Expand All @@ -43,7 +44,7 @@ impl DatabaseFactory {
Arc::new(PostgresDatabase::new(cfg, format))
}
DbType::Mysql => Arc::new(MySQLDatabase::new(cfg)),
DbType::Mariadb => Arc::new(MySQLDatabase::new(cfg)),
DbType::Mariadb => Arc::new(MariaDBDatabase::new(cfg)),
DbType::MongoDB => Arc::new(MongoDatabase::new(cfg)),
DbType::Sqlite => Arc::new(SqliteDatabase::new(cfg)),
DbType::Redis => Arc::new(RedisDatabase::new(cfg)),
Expand Down
66 changes: 66 additions & 0 deletions src/domain/mariadb/backup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use crate::domain::mariadb::connection::{select_mariadb_path, server_version};
use crate::services::config::DatabaseConfig;
use anyhow::{Context, Result};
use std::collections::HashMap;
use std::path::PathBuf;
use std::process::Command;
use tracing::{debug, error, info};

pub async fn run(
cfg: DatabaseConfig,
backup_dir: PathBuf,
env: HashMap<String, String>,
file_extension: &'static str,
) -> Result<PathBuf> {
tokio::task::spawn_blocking(move || -> Result<PathBuf> {
debug!("Starting backup for database {}", cfg.name);

let version = match futures::executor::block_on(server_version(&cfg)) {
Ok(v) => {
debug!("Mariadb version detected: {}", v);
v
}
Err(e) => {
error!("Failed to get server version for {}: {:?}", cfg.name, e);
return Err(e.into());
}
};

info!("Mariadb version found: {}", version);

let file_path = backup_dir.join(format!("{}{}", cfg.generated_id, file_extension));

let mariadb_dump = select_mariadb_path(&version).join("mariadb-dump");
info!("Mariadb dump found: {}", mariadb_dump.display());

let output = Command::new("mariadb-dump")
.arg("--host").arg(&cfg.host)
.arg("--port").arg(cfg.port.to_string())
.arg("--user").arg(&cfg.username)
.arg("--routines")
.arg("--events")
.arg("--triggers")
.arg("--single-transaction")
.arg("--quick")
.arg("--skip-lock-tables")
.arg("--add-drop-database")
.arg("--databases").arg(&cfg.database)
.arg("--compress")
.arg("--max-allowed-packet=512M")
.arg("--net-buffer-length=16K")
.arg("--default-character-set=utf8mb4")
.arg("-r").arg(&file_path)
.envs(env)
.output()
.with_context(|| format!("Failed to run mariadb-dump for {}", cfg.name))?;


if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
anyhow::bail!("Mariadb backup failed for {}: {}", cfg.name, stderr);
}

Ok(file_path)
})
.await?
}
45 changes: 45 additions & 0 deletions src/domain/mariadb/connection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use std::path::PathBuf;
use crate::services::config::DatabaseConfig;
use anyhow::Result;
use std::process::Command;

pub async fn server_version(cfg: &DatabaseConfig) -> Result<String> {
let output = Command::new("mariadb")
.arg("--host")
.arg(&cfg.host)
.arg("--port")
.arg(cfg.port.to_string())
.arg("--user")
.arg(&cfg.username)
.arg("-e")
.arg("SELECT VERSION();")
.env("MYSQL_PWD", &cfg.password)
.output()?;

if !output.status.success() {
let stderr = String::from_utf8_lossy(&output.stderr);
anyhow::bail!("Version query failed: {}", stderr);
}

let version = String::from_utf8_lossy(&output.stdout)
.lines()
.nth(1)
.unwrap_or_default()
.trim()
.to_string();

Ok(version)
}


pub fn select_mariadb_path(version: &str) -> PathBuf {
let mut parts = version.split('.');
let major = parts.next().and_then(|v| v.parse::<u32>().ok()).unwrap_or(10);
let minor = parts.next().and_then(|v| v.parse::<u32>().ok()).unwrap_or(0);

if major < 10 || (major == 10 && minor <= 6) {
"/usr/local/mariadb-10.6/bin".into()
} else {
"/usr/local/mariadb-12.1/bin".into()
}
}
Loading
Loading