headless_lms_server/programs/seed/
mod.rs1pub mod builder;
2pub mod seed_certificate_fonts;
3pub mod seed_courses;
4pub mod seed_exercise_services;
5pub mod seed_file_storage;
6pub mod seed_generic_emails;
7pub mod seed_helpers;
8pub mod seed_oauth_clients;
9pub mod seed_organizations;
10pub mod seed_playground_examples;
11pub mod seed_roles;
12mod seed_user_research_consents;
13pub mod seed_users;
14
15use std::{env, process::Command, sync::Arc, time::Duration};
16
17use crate::{
18 domain::models_requests::JwtKey, programs::seed::seed_oauth_clients::seed_oauth_clients,
19 setup_tracing,
20};
21
22use anyhow::Context;
23use futures::try_join;
24
25use headless_lms_utils::futures::run_parallelly;
26use sqlx::{Pool, Postgres, migrate::MigrateDatabase, postgres::PgPoolOptions};
27use tracing::info;
28
29pub async fn main() -> anyhow::Result<()> {
30 let base_url = std::env::var("BASE_URL").context("BASE_URL must be defined")?;
31 let db_pool = setup_seed_environment().await?;
32 let jwt_key = Arc::new(JwtKey::try_from_env().expect("Failed to create JwtKey"));
33
34 seed_helpers::init_seed_spec_fetcher(base_url.clone(), Arc::clone(&jwt_key))
36 .expect("Failed to initialize seed spec fetcher");
37
38 let (_, seed_users_result, _) = try_join!(
40 run_parallelly(seed_exercise_services::seed_exercise_services(
41 db_pool.clone()
42 )),
43 run_parallelly(seed_users::seed_users(db_pool.clone())),
44 run_parallelly(seed_playground_examples::seed_playground_examples(
45 db_pool.clone()
46 )),
47 )?;
48
49 let seed_file_storage_result = seed_file_storage::seed_file_storage().await?;
51
52 let (uh_cs_organization_result, _uh_mathstat_organization_id, _no_users_organization_id) = try_join!(
53 run_parallelly(seed_organizations::uh_cs::seed_organization_uh_cs(
54 db_pool.clone(),
55 seed_users_result,
56 base_url.clone(),
57 Arc::clone(&jwt_key),
58 seed_file_storage_result.clone()
59 )),
60 run_parallelly(
61 seed_organizations::uh_mathstat::seed_organization_uh_mathstat(
62 db_pool.clone(),
63 seed_users_result,
64 base_url.clone(),
65 Arc::clone(&jwt_key),
66 seed_file_storage_result.clone()
67 )
68 ),
69 run_parallelly(seed_organizations::no_users::seed_organization_no_users(
70 db_pool.clone()
71 ))
72 )?;
73
74 try_join!(
75 run_parallelly(seed_roles::seed_roles(
76 db_pool.clone(),
77 seed_users_result,
78 uh_cs_organization_result
79 )),
80 run_parallelly(seed_user_research_consents::seed_user_research_consents(
81 db_pool.clone(),
82 seed_users_result
83 )),
84 run_parallelly(seed_certificate_fonts::seed_certificate_fonts(
85 db_pool.clone()
86 )),
87 run_parallelly(seed_generic_emails::seed_generic_emails(
88 db_pool.clone(),
89 seed_users_result
90 )),
91 run_parallelly(seed_oauth_clients(db_pool.clone()))
92 )?;
93
94 Ok(())
95}
96
97async fn setup_seed_environment() -> anyhow::Result<Pool<Postgres>> {
98 unsafe { env::set_var("RUST_LOG", "info,sqlx=warn,headless_lms_models=info") };
100
101 dotenv::dotenv().ok();
102 setup_tracing()?;
103
104 let clean = env::args().any(|a| a == "clean");
105
106 let db_url = env::var("DATABASE_URL")?;
107 let db_pool = PgPoolOptions::new()
108 .max_connections(10)
109 .min_connections(5)
110 .acquire_timeout(Duration::from_secs(90))
112 .connect(&db_url)
113 .await?;
114
115 if clean {
116 info!("cleaning");
117 let status = Command::new("dropdb")
119 .args(["-U", "headless-lms"])
120 .args(["-h", "localhost"])
121 .args(["-p", "54328"])
122 .arg("--force")
123 .arg("-e")
124 .arg("headless_lms_dev")
125 .status()?;
126 assert!(status.success());
127 let db_url = env::var("DATABASE_URL")?;
128 Postgres::create_database(&db_url).await?;
129 }
130
131 if clean {
132 let mut conn = db_pool.acquire().await?;
133 info!("running migrations");
134 sqlx::migrate!("../migrations").run(&mut conn).await?;
135 }
136 Ok(db_pool)
137}