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