Test deploy docker log (#105)

* chore: try to fix logs in docker

* ci: test deploy

* ci: log level
This commit is contained in:
Nathan.fooo 2023-10-08 21:42:25 +08:00 committed by GitHub
parent 375c463566
commit a02da07627
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 71 additions and 58 deletions

View File

@ -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

1
.gitignore vendored
View File

@ -12,3 +12,4 @@ node_modules
**/libs/AppFlowy-Collab/
data/
.env
.logs

4
Cargo.lock generated
View File

@ -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",

View File

@ -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" }

View File

@ -43,4 +43,4 @@ AWS_SECRET_ACCESS_KEY=minioadmin
AWS_S3_BUCKET=appflowy
AWS_REGION=us-east-1
RUST_LOG=info
RUST_LOG=info

View File

@ -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!(

View File

@ -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

View File

@ -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,
}
})
}

View File

@ -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?;

View File

@ -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