From 3e18c840d195e735521136df94a14500d122eb52 Mon Sep 17 00:00:00 2001 From: Ilion Beyst Date: Tue, 18 Jan 2022 20:17:13 +0100 Subject: [PATCH] running a bot in docker PoC --- planetwars-matchrunner/src/bin/testmatch.rs | 111 ++++++++++++++++++++ planetwars-matchrunner/src/lib.rs | 6 +- 2 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 planetwars-matchrunner/src/bin/testmatch.rs diff --git a/planetwars-matchrunner/src/bin/testmatch.rs b/planetwars-matchrunner/src/bin/testmatch.rs new file mode 100644 index 0000000..97c00ed --- /dev/null +++ b/planetwars-matchrunner/src/bin/testmatch.rs @@ -0,0 +1,111 @@ +extern crate planetwars_matchrunner; +extern crate tokio; + +use std::collections::HashMap; +use std::io::{self, Write}; +use std::path::PathBuf; +use std::pin::Pin; +use std::sync::{Arc, Mutex}; + +use bollard::container::{self, LogOutput}; +use bollard::exec::StartExecResults; +use bollard::Docker; +use futures::{Stream, StreamExt}; +use planetwars_matchrunner::{ + match_context::{EventBus, MatchCtx, PlayerHandle}, + pw_match, MatchConfig, MatchMeta, PlayerInfo, +}; +use planetwars_rules::protocol as proto; +use planetwars_rules::PwConfig; +use std::env; +use tokio::io::{AsyncWrite, AsyncWriteExt}; + +const IMAGE: &'static str = "simplebot:latest"; + +#[tokio::main] +async fn main() { + let args: Vec = env::args().collect(); + assert!(args.len() >= 2); + let map_path = args[1].clone(); + _run_match(map_path).await; +} + +async fn _run_match(map_path: String) { + let docker = Docker::connect_with_socket_defaults().unwrap(); + create_player_process(&docker).await.unwrap(); +} + +async fn create_player_process(docker: &Docker) -> Result<(), bollard::errors::Error> { + let config = container::Config { + image: Some(IMAGE), + ..Default::default() + }; + + let response = docker.create_container::<&str, &str>(None, config).await?; + let container_id = response.id; + + docker + .start_container::(&container_id, None) + .await?; + + let exec_id = docker + .create_exec::<&str>( + &container_id, + bollard::exec::CreateExecOptions { + attach_stdin: Some(true), + attach_stdout: Some(true), + attach_stderr: Some(true), + cmd: Some(vec!["python", "simplebot.py"]), + ..Default::default() + }, + ) + .await + .unwrap() + .id; + + let start_exec_results = docker.start_exec(&exec_id, None).await?; + let (mut input, mut output) = match start_exec_results { + StartExecResults::Detached => panic!("failed to get io channels"), + StartExecResults::Attached { input, output } => (input, output), + }; + + let state = proto::State { + planets: vec![ + proto::Planet { + name: "a".to_string(), + owner: Some(1), + ship_count: 100, + x: -1.0, + y: 0.0, + }, + proto::Planet { + name: "b".to_string(), + owner: Some(2), + ship_count: 100, + x: 1.0, + y: 0.0, + }, + ], + expeditions: vec![], + }; + + let serialized = serde_json::to_vec(&state).unwrap(); + input.write_all(&serialized).await?; + input.write(b"\n").await?; + input.flush().await?; + + while let Some(item) = output.next().await { + let log_output = item.expect("failed to get log output"); + match log_output { + LogOutput::StdOut { message } => { + println!("stdout: {}", String::from_utf8_lossy(&message)); + } + LogOutput::StdErr { message } => { + println!("stderr: {}", String::from_utf8_lossy(&message)); + } + _ => (), + } + } + + Ok(()) +} diff --git a/planetwars-matchrunner/src/lib.rs b/planetwars-matchrunner/src/lib.rs index 50c6518..1f23551 100644 --- a/planetwars-matchrunner/src/lib.rs +++ b/planetwars-matchrunner/src/lib.rs @@ -1,6 +1,6 @@ -mod bot_runner; -mod match_context; -mod pw_match; +pub mod bot_runner; +pub mod match_context; +pub mod pw_match; use std::{ io::Write,