mirror of
https://github.com/Portabase/agent.git
synced 2026-09-11 02:27:10 +00:00
Compare commits
13 Commits
1.1.0
...
1.1.2-rc.2
| Author | SHA1 | Date | |
|---|---|---|---|
| 4de2b81b33 | |||
| b06f9d8186 | |||
| f5a2182723 | |||
| e8a96980f1 | |||
| a64792bcc6 | |||
| 2d4542be5f | |||
| 4a00ed574d | |||
| fd220598fc | |||
| d8b239a123 | |||
| ebf0526366 | |||
| 6461c1523b | |||
| 2809373de1 | |||
| 2bcb393d60 |
+2
-2
@@ -22,5 +22,5 @@ keywords:
|
||||
- self-hosted
|
||||
- portabase
|
||||
license: Apache-2.0
|
||||
version: 1.1.0
|
||||
date-released: "2026-02-13"
|
||||
version: 1.1.2-rc.2
|
||||
date-released: "2026-02-16"
|
||||
Generated
+1
-1
@@ -2851,7 +2851,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "portabase-agent"
|
||||
version = "1.1.0-rc.2"
|
||||
version = "1.1.2-rc.1"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"aes-gcm",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "portabase-agent"
|
||||
version = "1.1.0"
|
||||
version = "1.1.2-rc.2"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
+3
-4
@@ -11,13 +11,12 @@ services:
|
||||
# - ./databases.toml:/config/config.toml
|
||||
- cargo-registry:/usr/local/cargo/registry
|
||||
- cargo-git:/usr/local/cargo/git
|
||||
- cargo-target:/app/target
|
||||
# - cargo-target:/app/target
|
||||
environment:
|
||||
APP_ENV: development
|
||||
LOG: debug
|
||||
TZ: "Europe/Paris"
|
||||
EDGE_KEY: "eyJzZXJ2ZXJVcmwiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODciLCJhZ2VudElkIjoiMzI3YTU4ODktYzE0MC00ODMzLTk1ZWMtNTBmMmU2NTFlZmJhIiwibWFzdGVyS2V5QjY0IjoiQlhWM1hvbEM2NTZTVjdkTmdjV1BHUWxrKytycExJNmxHRGk3Q1BCNWllbz0ifQ=="
|
||||
# EDGE_KEY: "eyJzZXJ2ZXJVcmwiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODciLCJhZ2VudElkIjoiZWE2NTg1MDctZTA5My00NDUxLWIxZDAtMDgwZWZjMGNmNWYzIiwicHVibGljS2V5IjoiLS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tXG5NSUlCQ2dLQ0FRRUE5TWV4M2pmdnVLdFB5YU1ERnh2Ulp2dmd3YkRJQ2JzQi81Wll5NDNSVVRBaXZRYjJiSDdYXG5qRHBQd1lJeCs4UFBrbHlRbDVMQzV1UWZEaCs4SVd4OG1LZ3FvMXpWMkdiZXdGbEdEWFYxVEdyU1ZEU25aSWR4XG52bWdYc29EeXhVMlJvWUFUMS9YMWxuc2YxenZKdkFMTkhXdEhRdk42SjVDZTFSMmFsendVRGFEVXlJNzRmSldQXG5tNTh0SDMrYklXL0VVTXdjaWNxM0oySWw3Vm9KNkZNUHJQL1ZSOWEvdFF1SU1qa200MXpFY2NscExPa2luRkxuXG54NmVUWkFSZUpya2UrbnRvZ2t4TGEyRWV5a1lUNzB4V3hKNWp5ZExBVnRvNkkyQlVLVVJoTkowTUFaU29NYUtvXG5iMGJRcnY1UzExZWllMnMrT2I3aTYzSFpkVUx0UmV1MVJ3SURBUUFCXG4tLS0tLUVORCBSU0EgUFVCTElDIEtFWS0tLS0tXG4ifQ"
|
||||
EDGE_KEY: "eyJzZXJ2ZXJVcmwiOiJodHRwOi8vbG9jYWxob3N0Ojg4ODciLCJhZ2VudElkIjoiOWZjYjhmNjUtNTcyMC00N2M3LThkNWItYWFlMmVjOTc2OWU1IiwibWFzdGVyS2V5QjY0IjoiQlhWM1hvbEM2NTZTVjdkTmdjV1BHUWxrKytycExJNmxHRGk3Q1BCNWllbz0ifQ=="
|
||||
#POOLING: 1
|
||||
#DATABASES_CONFIG_FILE: "config.toml"
|
||||
extra_hosts:
|
||||
@@ -95,7 +94,7 @@ services:
|
||||
volumes:
|
||||
cargo-registry:
|
||||
cargo-git:
|
||||
cargo-target:
|
||||
# cargo-target:
|
||||
|
||||
|
||||
postgres-data:
|
||||
|
||||
@@ -1,19 +1,26 @@
|
||||
use crate::services::config::DatabaseConfig;
|
||||
use anyhow::Context;
|
||||
use std::collections::HashMap;
|
||||
use std::process::Command;
|
||||
use tokio::process::Command;
|
||||
use tokio::time::{Duration, timeout};
|
||||
|
||||
pub async fn run(cfg: DatabaseConfig, env: HashMap<String, String>) -> anyhow::Result<bool> {
|
||||
let output = Command::new("mysqladmin")
|
||||
.arg("--host")
|
||||
let mut cmd = Command::new("mysqladmin");
|
||||
cmd.arg("--host")
|
||||
.arg(cfg.host)
|
||||
.arg("--port")
|
||||
.arg(cfg.port.to_string())
|
||||
.arg("--user")
|
||||
.arg(cfg.username)
|
||||
.arg("ping")
|
||||
.envs(env)
|
||||
.output()
|
||||
.with_context(|| format!("Failed to ping MySQL server {}", cfg.name))?;
|
||||
Ok(output.status.success())
|
||||
.envs(env);
|
||||
|
||||
let result = timeout(Duration::from_secs(10), cmd.output()).await;
|
||||
|
||||
match result {
|
||||
Ok(output) => {
|
||||
let output = output?;
|
||||
Ok(output.status.success())
|
||||
}
|
||||
Err(_) => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
+48
-20
@@ -69,7 +69,6 @@ impl BackupService {
|
||||
return;
|
||||
}
|
||||
Ok(false) => {
|
||||
|
||||
match ctx
|
||||
.api
|
||||
.backup_create(
|
||||
@@ -85,13 +84,27 @@ impl BackupService {
|
||||
info!("Created temp directory {}", tmp_path.display());
|
||||
match BackupService::run(db_cfg, &tmp_path).await {
|
||||
Ok(mut result) => {
|
||||
let backup_id = backup_created_result.unwrap().backup.id;
|
||||
|
||||
if result.status == "failed" {
|
||||
error!("Backup failed early for {}", result.generated_id);
|
||||
|
||||
let service = BackupService { ctx: ctx.clone() };
|
||||
|
||||
let _ = service
|
||||
.send_result(result, vec![], &backup_id)
|
||||
.await;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if let Some(backup_file) = result.backup_file.take() {
|
||||
match compress_to_tar_gz_large(&backup_file).await {
|
||||
Ok(compression_result) => {
|
||||
result.backup_file =
|
||||
Some(compression_result.compressed_path);
|
||||
let service = BackupService { ctx: ctx.clone() };
|
||||
let backup_id = backup_created_result.unwrap().backup.id;
|
||||
match service
|
||||
.upload(
|
||||
result.clone(),
|
||||
@@ -107,7 +120,7 @@ impl BackupService {
|
||||
.send_result(
|
||||
result,
|
||||
upload_result,
|
||||
&backup_id
|
||||
&backup_id,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -147,7 +160,7 @@ impl BackupService {
|
||||
}
|
||||
Err(e) => error!("Backup creation failed: {}", e),
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(e) => error!("An error occurred while checking lock : {}", e),
|
||||
}
|
||||
}
|
||||
@@ -162,7 +175,16 @@ impl BackupService {
|
||||
let generated_id = cfg.generated_id.clone();
|
||||
let db_type = cfg.db_type.clone();
|
||||
|
||||
let reachable = db_instance.ping().await.unwrap_or(false);
|
||||
|
||||
let reachable = match db_instance.ping().await {
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
error!("Ping failed: {}", e);
|
||||
return Err(e.into());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
info!("Reachable: {}", reachable);
|
||||
if !reachable {
|
||||
return Ok(BackupResult {
|
||||
@@ -276,7 +298,7 @@ impl BackupService {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
match self.ctx.api.backup_upload_status(
|
||||
self.ctx.edge_key.agent_id.clone(),
|
||||
generated_id.clone(),
|
||||
@@ -284,12 +306,12 @@ impl BackupService {
|
||||
status,
|
||||
remote_path,
|
||||
total_size,
|
||||
backup_id
|
||||
backup_id,
|
||||
).await {
|
||||
Ok(_) => {
|
||||
upload_result
|
||||
},
|
||||
Err(err)=> {
|
||||
}
|
||||
Err(err) => {
|
||||
error!(
|
||||
"backup_upload_status failed (generated_id={}, storage_id={}): {}",
|
||||
generated_id, storage_id, err
|
||||
@@ -355,17 +377,23 @@ impl BackupService {
|
||||
"failed"
|
||||
};
|
||||
|
||||
let file_size = upload_results
|
||||
.iter()
|
||||
.map(|r| r.total_size)
|
||||
.try_fold((0u64, 0u64), |(sum, count), v| {
|
||||
match v {
|
||||
Some(size) => Ok((sum + size, count + 1)),
|
||||
None => Err(()), // stop and return None
|
||||
}
|
||||
})
|
||||
.ok()
|
||||
.map(|(sum, count)| sum / count);
|
||||
let file_size = if status == "failed" {
|
||||
None
|
||||
} else {
|
||||
let mut sum = 0u64;
|
||||
let mut count = 0u64;
|
||||
|
||||
for size in upload_results.iter().filter_map(|r| r.total_size) {
|
||||
sum += size;
|
||||
count += 1;
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(sum / count)
|
||||
}
|
||||
};
|
||||
|
||||
match self
|
||||
.ctx
|
||||
|
||||
@@ -61,8 +61,7 @@ impl StorageProvider for S3Provider {
|
||||
let upload = match build_stream(
|
||||
&file_path,
|
||||
encrypt,
|
||||
&ctx.edge_key.master_key_b64
|
||||
// encrypt.then(|| ctx.edge_key.public_key.as_bytes().to_vec()),
|
||||
&ctx.edge_key.master_key_b64,
|
||||
)
|
||||
.await
|
||||
{
|
||||
@@ -100,7 +99,7 @@ impl StorageProvider for S3Provider {
|
||||
"static-creds",
|
||||
);
|
||||
|
||||
let region = Region::new(config.region.clone().unwrap_or("eu-central-3".to_string()));
|
||||
let region = Region::new(config.region.clone().unwrap_or("us-east-1".to_string()));
|
||||
|
||||
let sdk_config = s3::config::Builder::new()
|
||||
.credentials_provider(credentials)
|
||||
@@ -284,33 +283,6 @@ impl StorageProvider for S3Provider {
|
||||
remote_file_path
|
||||
);
|
||||
|
||||
// if let Some(enc) = upload.encryption {
|
||||
// let meta = EncryptionMetadataFile {
|
||||
// version: 1,
|
||||
// cipher: "AES-256-CBC+RSA-OAEP-SHA256".to_string(),
|
||||
// encrypted_aes_key_b64: general_purpose::STANDARD
|
||||
// .encode(enc.encrypted_aes_key),
|
||||
// iv_b64: general_purpose::STANDARD.encode(enc.iv),
|
||||
// };
|
||||
//
|
||||
// let meta_toml = toml::to_string(&meta).expect("Serialization error");
|
||||
//
|
||||
// let meta_key = format!("{}.meta", remote_file_path);
|
||||
//
|
||||
// client
|
||||
// .put_object()
|
||||
// .bucket(bucket)
|
||||
// .key(&meta_key)
|
||||
// .body(ByteStream::from(meta_toml.into_bytes()))
|
||||
// .content_type("application/toml")
|
||||
// .send()
|
||||
// .await
|
||||
// .map_err(|e| {
|
||||
// error!("Metadata upload failed: {}", e);
|
||||
// e
|
||||
// })
|
||||
// .unwrap();
|
||||
// }
|
||||
|
||||
UploadResult {
|
||||
storage_id: storage.id.clone(),
|
||||
|
||||
Reference in New Issue
Block a user