save all uploaded code bundles in database
This commit is contained in:
parent
6ef6a872fe
commit
22a8f3d619
9 changed files with 60 additions and 26 deletions
|
@ -8,7 +8,7 @@ CREATE UNIQUE INDEX bots_index ON bots(owner_id, name);
|
|||
|
||||
CREATE TABLE code_bundles (
|
||||
id serial PRIMARY KEY,
|
||||
bot_id integer REFERENCES bots(id) NOT NULL,
|
||||
bot_id integer REFERENCES bots(id),
|
||||
path text NOT NULL,
|
||||
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
|
@ -42,14 +42,14 @@ pub fn find_all_bots(conn: &PgConnection) -> QueryResult<Vec<Bot>> {
|
|||
#[derive(Insertable)]
|
||||
#[table_name = "code_bundles"]
|
||||
pub struct NewCodeBundle<'a> {
|
||||
pub bot_id: i32,
|
||||
pub bot_id: Option<i32>,
|
||||
pub path: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Queryable, Serialize, Deserialize, Debug)]
|
||||
pub struct CodeBundle {
|
||||
pub id: i32,
|
||||
pub bot_id: i32,
|
||||
pub bot_id: Option<i32>,
|
||||
pub path: String,
|
||||
pub created_at: chrono::NaiveDateTime,
|
||||
}
|
||||
|
|
|
@ -3,15 +3,17 @@ extern crate diesel;
|
|||
|
||||
pub mod db;
|
||||
pub mod db_types;
|
||||
pub mod modules;
|
||||
pub mod routes;
|
||||
pub mod schema;
|
||||
pub mod util;
|
||||
|
||||
use std::ops::Deref;
|
||||
|
||||
use axum;
|
||||
use bb8::PooledConnection;
|
||||
use bb8::{Pool, PooledConnection};
|
||||
use bb8_diesel::{self, DieselConnectionManager};
|
||||
use diesel::PgConnection;
|
||||
use diesel::{Connection, PgConnection};
|
||||
use serde::Deserialize;
|
||||
|
||||
use axum::{
|
||||
|
@ -29,9 +31,14 @@ const MAPS_DIR: &str = "./data/maps";
|
|||
|
||||
type ConnectionPool = bb8::Pool<DieselConnectionManager<PgConnection>>;
|
||||
|
||||
pub async fn api(configuration: Configuration) -> Router {
|
||||
let manager = DieselConnectionManager::<PgConnection>::new(configuration.database_url);
|
||||
pub async fn prepare_db(database_url: &str) -> Pool<DieselConnectionManager<PgConnection>> {
|
||||
let manager = DieselConnectionManager::<PgConnection>::new(database_url);
|
||||
let pool = bb8::Pool::builder().build(manager).await.unwrap();
|
||||
return pool;
|
||||
}
|
||||
|
||||
pub async fn api(configuration: Configuration) -> Router {
|
||||
let db_pool = prepare_db(&configuration.database_url).await;
|
||||
|
||||
let api = Router::new()
|
||||
.route("/register", post(routes::users::register))
|
||||
|
@ -57,7 +64,7 @@ pub async fn api(configuration: Configuration) -> Router {
|
|||
get(routes::matches::get_match_log),
|
||||
)
|
||||
.route("/submit_bot", post(routes::demo::submit_bot))
|
||||
.layer(AddExtensionLayer::new(pool));
|
||||
.layer(AddExtensionLayer::new(db_pool));
|
||||
api
|
||||
}
|
||||
|
||||
|
|
23
planetwars-server/src/modules/bots.rs
Normal file
23
planetwars-server/src/modules/bots.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use diesel::{PgConnection, QueryResult};
|
||||
|
||||
use crate::{db, util::gen_alphanumeric, BOTS_DIR};
|
||||
|
||||
pub fn save_code_bundle(
|
||||
bot_code: &str,
|
||||
bot_id: Option<i32>,
|
||||
conn: &PgConnection,
|
||||
) -> QueryResult<db::bots::CodeBundle> {
|
||||
let bundle_name = gen_alphanumeric(16);
|
||||
|
||||
let code_bundle_dir = PathBuf::from(BOTS_DIR).join(&bundle_name);
|
||||
std::fs::create_dir(&code_bundle_dir).unwrap();
|
||||
std::fs::write(code_bundle_dir.join("bot.py"), bot_code).unwrap();
|
||||
|
||||
let new_code_bundle = db::bots::NewCodeBundle {
|
||||
bot_id,
|
||||
path: &bundle_name,
|
||||
};
|
||||
db::bots::create_code_bundle(&new_code_bundle, conn)
|
||||
}
|
3
planetwars-server/src/modules/mod.rs
Normal file
3
planetwars-server/src/modules/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
// This module implements general domain logic, not directly
|
||||
// tied to the database or API layers.
|
||||
pub mod bots;
|
|
@ -97,7 +97,7 @@ pub async fn upload_code_multipart(
|
|||
.map_err(|_| StatusCode::BAD_REQUEST)?;
|
||||
|
||||
let bundle = bots::NewCodeBundle {
|
||||
bot_id: bot.id,
|
||||
bot_id: Some(bot.id),
|
||||
path: &folder_name,
|
||||
};
|
||||
let code_bundle =
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use crate::db::matches::{self, MatchState};
|
||||
use crate::modules::bots::save_code_bundle;
|
||||
use crate::util::gen_alphanumeric;
|
||||
use crate::{ConnectionPool, BOTS_DIR, MAPS_DIR, MATCHES_DIR};
|
||||
use axum::extract::Extension;
|
||||
use axum::Json;
|
||||
use hyper::StatusCode;
|
||||
use planetwars_matchrunner::{docker_runner::DockerBotSpec, run_match, MatchConfig, MatchPlayer};
|
||||
use rand::{distributions::Alphanumeric, Rng};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
@ -15,6 +16,7 @@ const SIMPLEBOT_PATH: &'static str = "../simplebot";
|
|||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct SubmitBotParams {
|
||||
pub bot_name: Option<String>,
|
||||
pub code: String,
|
||||
}
|
||||
|
||||
|
@ -32,14 +34,12 @@ pub async fn submit_bot(
|
|||
) -> Result<Json<SubmitBotResponse>, StatusCode> {
|
||||
let conn = pool.get().await.expect("could not get database connection");
|
||||
|
||||
let uploaded_bot_uuid: String = gen_alphanumeric(16);
|
||||
let code_bundle = save_code_bundle(¶ms.code, None, &conn)
|
||||
// TODO: can we recover from this?
|
||||
.expect("could not save bot code");
|
||||
|
||||
let log_file_name = format!("{}.log", gen_alphanumeric(16));
|
||||
|
||||
// store uploaded bot
|
||||
let uploaded_bot_dir = PathBuf::from(BOTS_DIR).join(&uploaded_bot_uuid);
|
||||
std::fs::create_dir(&uploaded_bot_dir).unwrap();
|
||||
std::fs::write(uploaded_bot_dir.join("bot.py"), params.code.as_bytes()).unwrap();
|
||||
|
||||
let uploaded_bot_dir = PathBuf::from(BOTS_DIR).join(&code_bundle.path);
|
||||
// play the match
|
||||
let match_config = MatchConfig {
|
||||
map_path: PathBuf::from(MAPS_DIR).join("hex.json"),
|
||||
|
@ -95,11 +95,3 @@ async fn run_match_task(match_id: i32, match_config: MatchConfig, connection_poo
|
|||
matches::set_match_state(match_id, MatchState::Finished, &conn)
|
||||
.expect("failed to update match state");
|
||||
}
|
||||
|
||||
pub fn gen_alphanumeric(length: usize) -> String {
|
||||
rand::thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(length)
|
||||
.map(char::from)
|
||||
.collect()
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ table! {
|
|||
|
||||
code_bundles (id) {
|
||||
id -> Int4,
|
||||
bot_id -> Int4,
|
||||
bot_id -> Nullable<Int4>,
|
||||
path -> Text,
|
||||
created_at -> Timestamp,
|
||||
}
|
||||
|
|
9
planetwars-server/src/util.rs
Normal file
9
planetwars-server/src/util.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
use rand::{distributions::Alphanumeric, Rng};
|
||||
|
||||
pub fn gen_alphanumeric(length: usize) -> String {
|
||||
rand::thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(length)
|
||||
.map(char::from)
|
||||
.collect()
|
||||
}
|
Loading…
Reference in a new issue