Test deploy docker log (#105)
* chore: try to fix logs in docker * ci: test deploy * ci: log level
This commit is contained in:
parent
375c463566
commit
a02da07627
|
|
@ -1,7 +1,9 @@
|
|||
name: Deployment for Test Environment
|
||||
on:
|
||||
push:
|
||||
branches: main
|
||||
branches:
|
||||
- 'main'
|
||||
- 'test_deploy_*'
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
|
|
@ -12,7 +14,7 @@ jobs:
|
|||
- name: Set up env vars
|
||||
run: |
|
||||
cp dev.env .env
|
||||
|
||||
|
||||
# log level
|
||||
sed -i 's|RUST_LOG=.*|RUST_LOG=trace|' .env
|
||||
|
||||
|
|
|
|||
|
|
@ -12,3 +12,4 @@ node_modules
|
|||
**/libs/AppFlowy-Collab/
|
||||
data/
|
||||
.env
|
||||
.logs
|
||||
|
|
@ -866,7 +866,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "collab"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=489cae0#489cae080419bd327282f974efe49ee447390b1d"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4a4df0b#4a4df0b287f197db99a02748548a5c0836c91588"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
|
@ -885,7 +885,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "collab-define"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=489cae0#489cae080419bd327282f974efe49ee447390b1d"
|
||||
source = "git+https://github.com/AppFlowy-IO/AppFlowy-Collab?rev=4a4df0b#4a4df0b287f197db99a02748548a5c0836c91588"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ sqlx = { version = "0.7", default-features = false, features = ["runtime-tokio-r
|
|||
async-trait = "0.1.73"
|
||||
|
||||
# collab
|
||||
collab = { version = "0.1.0" }
|
||||
collab = { version = "0.1.0", features = ["async-plugin"] }
|
||||
|
||||
#Local crate
|
||||
token = { path = "libs/token" }
|
||||
|
|
@ -126,8 +126,8 @@ lto = false
|
|||
opt-level = 3
|
||||
|
||||
[patch.crates-io]
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "489cae0" }
|
||||
collab-define = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "489cae0" }
|
||||
collab = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4a4df0b" }
|
||||
collab-define = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev = "4a4df0b" }
|
||||
|
||||
# Comment the above and uncomment the below to use local version of collab by cloning the repo and placing it in libs folder
|
||||
#collab = { path = "libs/AppFlowy-Collab/collab" }
|
||||
|
|
|
|||
2
dev.env
2
dev.env
|
|
@ -43,4 +43,4 @@ AWS_SECRET_ACCESS_KEY=minioadmin
|
|||
AWS_S3_BUCKET=appflowy
|
||||
AWS_REGION=us-east-1
|
||||
|
||||
RUST_LOG=info
|
||||
RUST_LOG=info
|
||||
|
|
|
|||
|
|
@ -100,6 +100,8 @@ pub struct GoTrueError {
|
|||
pub error_id: Option<String>,
|
||||
}
|
||||
|
||||
impl std::error::Error for GoTrueError {}
|
||||
|
||||
impl Display for GoTrueError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.write_fmt(format_args!(
|
||||
|
|
|
|||
|
|
@ -1,21 +1,14 @@
|
|||
use crate::collaborate::{CollabBroadcast, CollabStoragePlugin, Subscription};
|
||||
|
||||
use crate::entities::RealtimeUser;
|
||||
use anyhow::Error;
|
||||
use collab::core::collab::MutexCollab;
|
||||
use collab::core::origin::CollabOrigin;
|
||||
use collab::preclude::Collab;
|
||||
use collab_define::CollabType;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::Error;
|
||||
|
||||
use database::collab::CollabStorage;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use crate::entities::RealtimeUser;
|
||||
use tokio::task::spawn_blocking;
|
||||
|
||||
use tracing::{error, warn};
|
||||
|
|
@ -115,7 +108,7 @@ where
|
|||
Arc::downgrade(&group),
|
||||
);
|
||||
collab.lock().add_plugin(Arc::new(plugin));
|
||||
collab.async_initialize().await;
|
||||
collab.lock_arc().initialize().await;
|
||||
|
||||
self
|
||||
.storage
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ use actix_web::cookie::Key;
|
|||
use actix_web::{dev::Server, web, web::Data, App, HttpServer};
|
||||
|
||||
use actix::Actor;
|
||||
use anyhow::{Context, Error};
|
||||
use openssl::ssl::{SslAcceptor, SslAcceptorBuilder, SslFiletype, SslMethod};
|
||||
use openssl::x509::X509;
|
||||
use secrecy::{ExposeSecret, Secret};
|
||||
|
|
@ -114,17 +115,17 @@ fn get_certificate_and_server_key(config: &Config) -> Option<(Secret<String>, Se
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn init_state(config: &Config) -> AppState {
|
||||
let pg_pool = get_connection_pool(&config.database).await;
|
||||
migrate(&pg_pool).await;
|
||||
pub async fn init_state(config: &Config) -> Result<AppState, Error> {
|
||||
let pg_pool = get_connection_pool(&config.database).await?;
|
||||
migrate(&pg_pool).await?;
|
||||
|
||||
let s3_bucket = get_aws_s3_bucket(&config.s3).await;
|
||||
let gotrue_client = get_gotrue_client(&config.gotrue).await;
|
||||
setup_admin_account(&gotrue_client, &pg_pool, &config.gotrue).await;
|
||||
let redis_client = get_redis_client(config.redis_uri.expose_secret()).await;
|
||||
let collab_storage = init_storage(config, pg_pool.clone()).await;
|
||||
let s3_bucket = get_aws_s3_bucket(&config.s3).await?;
|
||||
let gotrue_client = get_gotrue_client(&config.gotrue).await?;
|
||||
setup_admin_account(&gotrue_client, &pg_pool, &config.gotrue).await?;
|
||||
let redis_client = get_redis_client(config.redis_uri.expose_secret()).await?;
|
||||
let collab_storage = init_storage(config, pg_pool.clone()).await?;
|
||||
|
||||
AppState {
|
||||
Ok(AppState {
|
||||
pg_pool,
|
||||
config: Arc::new(config.clone()),
|
||||
user: Arc::new(Default::default()),
|
||||
|
|
@ -133,17 +134,20 @@ pub async fn init_state(config: &Config) -> AppState {
|
|||
s3_bucket,
|
||||
redis_client,
|
||||
collab_storage,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async fn setup_admin_account(
|
||||
gotrue_client: &gotrue::api::Client,
|
||||
pg_pool: &PgPool,
|
||||
gotrue_setting: &GoTrueSetting,
|
||||
) {
|
||||
) -> Result<(), Error> {
|
||||
let admin_email = gotrue_setting.admin_email.as_str();
|
||||
let password = gotrue_setting.admin_password.as_str();
|
||||
gotrue_client.sign_up(admin_email, password).await.unwrap();
|
||||
gotrue_client
|
||||
.sign_up(admin_email, password)
|
||||
.await
|
||||
.context("failed to sign-up for admin user")?;
|
||||
|
||||
// Unable to use query! macro here instead
|
||||
// because of the auth is a not default schema
|
||||
|
|
@ -158,25 +162,30 @@ async fn setup_admin_account(
|
|||
.bind(admin_email)
|
||||
.execute(pg_pool)
|
||||
.await
|
||||
.unwrap();
|
||||
.context("failed to update the admin user")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_redis_client(redis_uri: &str) -> redis::aio::ConnectionManager {
|
||||
redis::Client::open(redis_uri)
|
||||
.unwrap()
|
||||
async fn get_redis_client(redis_uri: &str) -> Result<redis::aio::ConnectionManager, Error> {
|
||||
let manager = redis::Client::open(redis_uri)
|
||||
.context("failed to connect to redis")?
|
||||
.get_tokio_connection_manager()
|
||||
.await
|
||||
.unwrap()
|
||||
.context("failed to get the connection manager")?;
|
||||
Ok(manager)
|
||||
}
|
||||
|
||||
async fn get_aws_s3_bucket(s3_setting: &S3Setting) -> s3::Bucket {
|
||||
async fn get_aws_s3_bucket(s3_setting: &S3Setting) -> Result<s3::Bucket, Error> {
|
||||
let region = {
|
||||
match s3_setting.use_minio {
|
||||
true => s3::Region::Custom {
|
||||
region: "".to_owned(),
|
||||
endpoint: s3_setting.minio_url.to_owned(),
|
||||
},
|
||||
false => s3_setting.region.parse::<s3::Region>().unwrap(),
|
||||
false => s3_setting
|
||||
.region
|
||||
.parse::<s3::Region>()
|
||||
.context("failed to parser s3 setting")?,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -196,16 +205,14 @@ async fn get_aws_s3_bucket(s3_setting: &S3Setting) -> s3::Bucket {
|
|||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => {},
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => match e {
|
||||
s3::error::S3Error::Http(409, _) => {}, // Bucket already exists
|
||||
_ => panic!("Failed to create bucket: {:?}", e),
|
||||
s3::error::S3Error::Http(409, _) => Ok(()), // Bucket already exists
|
||||
_ => Err(e),
|
||||
},
|
||||
}
|
||||
}?;
|
||||
|
||||
s3::Bucket::new(&s3_setting.bucket, region.clone(), cred.clone())
|
||||
.unwrap()
|
||||
.with_path_style()
|
||||
Ok(s3::Bucket::new(&s3_setting.bucket, region.clone(), cred.clone())?.with_path_style())
|
||||
}
|
||||
|
||||
// async fn get_aws_s3_client() -> aws_sdk_s3::Client {
|
||||
|
|
@ -226,28 +233,28 @@ async fn get_aws_s3_bucket(s3_setting: &S3Setting) -> s3::Bucket {
|
|||
// client
|
||||
// }
|
||||
|
||||
async fn get_connection_pool(setting: &DatabaseSetting) -> PgPool {
|
||||
async fn get_connection_pool(setting: &DatabaseSetting) -> Result<PgPool, Error> {
|
||||
PgPoolOptions::new()
|
||||
.acquire_timeout(std::time::Duration::from_secs(5))
|
||||
.connect_with(setting.with_db())
|
||||
.await
|
||||
.expect("Failed to connect to Postgres")
|
||||
.context("failed to connect to postgres database")
|
||||
}
|
||||
|
||||
async fn migrate(pool: &PgPool) {
|
||||
async fn migrate(pool: &PgPool) -> Result<(), Error> {
|
||||
sqlx::migrate!("./migrations")
|
||||
.run(pool)
|
||||
.await
|
||||
.expect("Failed to run migrations");
|
||||
.context("failed to run migrations")
|
||||
}
|
||||
|
||||
async fn get_gotrue_client(setting: &GoTrueSetting) -> gotrue::api::Client {
|
||||
async fn get_gotrue_client(setting: &GoTrueSetting) -> Result<gotrue::api::Client, Error> {
|
||||
let gotrue_client = gotrue::api::Client::new(reqwest::Client::new(), &setting.base_url);
|
||||
gotrue_client
|
||||
.health()
|
||||
.await
|
||||
.expect("Failed to connect to GoTrue");
|
||||
gotrue_client
|
||||
.context("failed to connect to GoTrue")?;
|
||||
Ok(gotrue_client)
|
||||
}
|
||||
|
||||
fn make_ssl_acceptor_builder(certificate: Secret<String>) -> SslAcceptorBuilder {
|
||||
|
|
@ -269,10 +276,13 @@ fn make_ssl_acceptor_builder(certificate: Secret<String>) -> SslAcceptorBuilder
|
|||
builder
|
||||
}
|
||||
|
||||
pub async fn init_storage(_config: &Config, pg_pool: PgPool) -> Storage<CollabStorageProxy> {
|
||||
pub async fn init_storage(
|
||||
_config: &Config,
|
||||
pg_pool: PgPool,
|
||||
) -> Result<Storage<CollabStorageProxy>, Error> {
|
||||
let collab_storage = CollabPostgresDBStorageImpl::new(pg_pool);
|
||||
let proxy = CollabStorageProxy::new(collab_storage);
|
||||
Storage {
|
||||
Ok(Storage {
|
||||
collab_storage: proxy,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ use appflowy_cloud::telemetry::{get_subscriber, init_subscriber};
|
|||
#[actix_web::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
let level = std::env::var("RUST_LOG").unwrap_or("info".to_string());
|
||||
println!("Start AppFlowy Cloud with RUST_LOG={}", level);
|
||||
|
||||
let mut filters = vec![];
|
||||
filters.push(format!("actix_web={}", level));
|
||||
filters.push(format!("collab={}", level));
|
||||
|
|
@ -21,8 +23,10 @@ async fn main() -> anyhow::Result<()> {
|
|||
);
|
||||
init_subscriber(subscriber);
|
||||
|
||||
let configuration = get_configuration().expect("Failed to read configuration.");
|
||||
let state = init_state(&configuration).await;
|
||||
let configuration = get_configuration().expect("The configuration should be configured.");
|
||||
let state = init_state(&configuration)
|
||||
.await
|
||||
.expect("The AppState should be initialized");
|
||||
let application = Application::build(configuration, state).await?;
|
||||
application.run_until_stopped().await?;
|
||||
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ impl TestClient {
|
|||
.to_string()
|
||||
}
|
||||
|
||||
#[allow(clippy::await_holding_lock)]
|
||||
pub(crate) async fn create_collab(
|
||||
&mut self,
|
||||
workspace_id: &str,
|
||||
|
|
@ -143,7 +144,7 @@ impl TestClient {
|
|||
);
|
||||
|
||||
collab.lock().add_plugin(Arc::new(sync_plugin));
|
||||
collab.async_initialize().await;
|
||||
collab.lock().initialize().await;
|
||||
let test_collab = TestCollab { origin, collab };
|
||||
self
|
||||
.collab_by_object_id
|
||||
|
|
|
|||
Loading…
Reference in New Issue