mirror of
https://codeberg.org/icewind/haze.git
synced 2026-06-03 17:14:08 +02:00
wip
This commit is contained in:
parent
949fb47cac
commit
afb7d0ae6f
6 changed files with 1590 additions and 3 deletions
1243
Cargo.lock
generated
Normal file
1243
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -4,6 +4,10 @@ version = "0.1.0"
|
|||
authors = ["Robin Appelman <robin@icewind.nl>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
bollard = "0.10"
|
||||
color-eyre = "0.5"
|
||||
min-id = "0.1"
|
||||
maplit = "1"
|
||||
camino = "1"
|
||||
tokio = { version = "1" , features = ["fs", "macros"] }
|
||||
309
src/cloud.rs
Normal file
309
src/cloud.rs
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
use crate::config::HazeConfig;
|
||||
use bollard::container::{Config, CreateContainerOptions};
|
||||
use bollard::models::HostConfig;
|
||||
use bollard::network::CreateNetworkOptions;
|
||||
use bollard::Docker;
|
||||
use camino::Utf8Path;
|
||||
use color_eyre::{eyre::WrapErr, Report, Result};
|
||||
use min_id::generate_id;
|
||||
use tokio::fs::{create_dir_all, write};
|
||||
|
||||
pub enum Database {
|
||||
Sqlite,
|
||||
Mysql,
|
||||
Mysql80,
|
||||
Mysql57,
|
||||
Mysql56,
|
||||
MariaDB,
|
||||
MariaDB101,
|
||||
MariaDB102,
|
||||
MariaDB103,
|
||||
MariaDB104,
|
||||
MariaDB105,
|
||||
Postgres,
|
||||
Postgres9,
|
||||
Postgres10,
|
||||
Postgres11,
|
||||
Postgres12,
|
||||
Postgres13,
|
||||
}
|
||||
|
||||
impl Default for Database {
|
||||
fn default() -> Self {
|
||||
Database::Sqlite
|
||||
}
|
||||
}
|
||||
|
||||
impl Database {
|
||||
pub fn image(&self) -> &'static str {
|
||||
match self {
|
||||
Database::Sqlite => "",
|
||||
Database::Mysql => "mysql",
|
||||
Database::Mysql80 => "mysql:8",
|
||||
Database::Mysql57 => "mysql:5.7",
|
||||
Database::Mysql56 => "mysql:5.6",
|
||||
Database::MariaDB => "mariadb",
|
||||
Database::MariaDB101 => "mariadb:10.1",
|
||||
Database::MariaDB102 => "mariadb:10.2",
|
||||
Database::MariaDB103 => "mariadb:10.3",
|
||||
Database::MariaDB104 => "mariadb:10.4",
|
||||
Database::MariaDB105 => "mariadb:10.5",
|
||||
Database::Postgres => "postgresql",
|
||||
Database::Postgres9 => "postgresql:9",
|
||||
Database::Postgres10 => "postgresql:10",
|
||||
Database::Postgres11 => "postgresql:11",
|
||||
Database::Postgres12 => "postgresql:12",
|
||||
Database::Postgres13 => "postgresql:13",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
Database::Sqlite => "sqlite",
|
||||
Database::Mysql
|
||||
| Database::Mysql80
|
||||
| Database::Mysql57
|
||||
| Database::Mysql56
|
||||
| Database::MariaDB
|
||||
| Database::MariaDB101
|
||||
| Database::MariaDB102
|
||||
| Database::MariaDB103
|
||||
| Database::MariaDB104
|
||||
| Database::MariaDB105 => "mysql",
|
||||
Database::Postgres
|
||||
| Database::Postgres9
|
||||
| Database::Postgres10
|
||||
| Database::Postgres11
|
||||
| Database::Postgres12
|
||||
| Database::Postgres13 => "pgsql",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn env(&self) -> Vec<&'static str> {
|
||||
match self {
|
||||
Database::Sqlite => Vec::new(),
|
||||
Database::Mysql
|
||||
| Database::Mysql80
|
||||
| Database::Mysql57
|
||||
| Database::Mysql56
|
||||
| Database::MariaDB
|
||||
| Database::MariaDB101
|
||||
| Database::MariaDB102
|
||||
| Database::MariaDB103
|
||||
| Database::MariaDB104
|
||||
| Database::MariaDB105 => vec![
|
||||
"MYSQL_ROOT_PASSWORD=haze",
|
||||
"MYSQL_PASSWORD=haze",
|
||||
"MYSQL_USER=haze",
|
||||
"MYSQL_DATABASE=haze",
|
||||
],
|
||||
Database::Postgres
|
||||
| Database::Postgres9
|
||||
| Database::Postgres10
|
||||
| Database::Postgres11
|
||||
| Database::Postgres12
|
||||
| Database::Postgres13 => vec![
|
||||
"POSTGRES_PASSWORD=haze",
|
||||
"POSTGRES_USER=haze",
|
||||
"POSTGRES_DATABASE=haze",
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn spawn(
|
||||
&self,
|
||||
docker: &mut Docker,
|
||||
cloud_id: &str,
|
||||
network: &str,
|
||||
) -> Result<Option<String>> {
|
||||
if matches!(self, Database::Sqlite) {
|
||||
return Ok(None);
|
||||
}
|
||||
let options = Some(CreateContainerOptions {
|
||||
name: format!("{}-db", cloud_id),
|
||||
});
|
||||
let config = Config {
|
||||
image: Some(self.image()),
|
||||
env: Some(self.env()),
|
||||
host_config: Some(HostConfig {
|
||||
network_mode: Some(network.to_string()),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
Ok(Some(docker.create_container(options, config).await?.id))
|
||||
}
|
||||
}
|
||||
|
||||
pub enum PhpVersion {
|
||||
Latest,
|
||||
// Php80,
|
||||
Php74,
|
||||
// Php73,
|
||||
}
|
||||
|
||||
impl PhpVersion {
|
||||
fn image(&self) -> &'static str {
|
||||
// for now only 7.4
|
||||
match self {
|
||||
PhpVersion::Latest => "icewind1991/nextcloud-dev:7",
|
||||
PhpVersion::Php74 => "icewind1991/nextcloud-dev:7",
|
||||
}
|
||||
}
|
||||
|
||||
async fn spawn(
|
||||
&self,
|
||||
docker: &mut Docker,
|
||||
id: &str,
|
||||
env: Vec<String>,
|
||||
network: &str,
|
||||
links: Vec<String>,
|
||||
volumes: Vec<String>,
|
||||
) -> Result<String> {
|
||||
let options = Some(CreateContainerOptions {
|
||||
name: id.to_string(),
|
||||
});
|
||||
let config = Config {
|
||||
image: Some(self.image().to_string()),
|
||||
env: Some(env),
|
||||
host_config: Some(HostConfig {
|
||||
network_mode: Some(network.to_string()),
|
||||
links: Some(links),
|
||||
binds: Some(volumes),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
};
|
||||
Ok(docker.create_container(options, config).await?.id)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for PhpVersion {
|
||||
fn default() -> Self {
|
||||
PhpVersion::Latest
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct CloudOptions {
|
||||
db: Database,
|
||||
php: PhpVersion,
|
||||
}
|
||||
|
||||
pub struct Cloud {
|
||||
id: String,
|
||||
network: String,
|
||||
containers: Vec<String>,
|
||||
}
|
||||
|
||||
impl Cloud {
|
||||
pub async fn create(
|
||||
docker: &mut Docker,
|
||||
options: CloudOptions,
|
||||
config: HazeConfig,
|
||||
) -> Result<Self> {
|
||||
let id = generate_id();
|
||||
|
||||
setup_workdir(&config.work_dir, &id)
|
||||
.await
|
||||
.wrap_err("Failed to setup work directories")?;
|
||||
|
||||
let network = docker
|
||||
.create_network(CreateNetworkOptions {
|
||||
name: format!("cloud-{}", id),
|
||||
..Default::default()
|
||||
})
|
||||
.await?
|
||||
.id
|
||||
.ok_or(Report::msg("No network id in response"))
|
||||
.wrap_err("Failed to create network")?;
|
||||
|
||||
let mut containers = Vec::new();
|
||||
let mut links = Vec::new();
|
||||
let mut env = vec!["PHP_IDE_CONFIG=serverName=haze".to_string()];
|
||||
let volumes = vec![
|
||||
format!("{}:/var/www/html", config.sources_root),
|
||||
format!("{}/{}/data:/var/www/html/data", config.work_dir, id),
|
||||
format!("{}/{}/config:/var/www/html/config", config.work_dir, id),
|
||||
format!(
|
||||
"{}/{}/data-autotest:/var/www/html/data-autotest",
|
||||
config.work_dir, id
|
||||
),
|
||||
format!(
|
||||
"{}/{}/skeleton:/var/www/html/core/skeleton",
|
||||
config.work_dir, id
|
||||
),
|
||||
format!(
|
||||
"{}/{}/skeleton/welcome.txt:/var/www/html/core/skeleton/welcome.txt:ro",
|
||||
config.work_dir, id
|
||||
),
|
||||
format!(
|
||||
"{}/{}/integration/vendor:/var/www/html/build/integration/vendor",
|
||||
config.work_dir, id
|
||||
),
|
||||
format!(
|
||||
"{}/{}/integration/work:/var/www/html/build/integration/work",
|
||||
config.work_dir, id
|
||||
),
|
||||
format!(
|
||||
"{}/{}/integration/output:/var/www/html/build/integration/output",
|
||||
config.work_dir, id
|
||||
),
|
||||
format!(
|
||||
"{}/{}/integration/composer.lock:/var/www/html/build/integration/composer.lock",
|
||||
config.work_dir, id
|
||||
),
|
||||
format!(
|
||||
"{}/composer/cache:/var/www/.composer/cache",
|
||||
config.work_dir
|
||||
),
|
||||
format!(
|
||||
"{}/phpunit-cache:/var/www/html/tests/.phpunit.results.cache",
|
||||
config.work_dir
|
||||
),
|
||||
];
|
||||
|
||||
if let Some(db) = options
|
||||
.db
|
||||
.spawn(docker, &id, &network)
|
||||
.await
|
||||
.wrap_err("Failed to start database")?
|
||||
{
|
||||
containers.push(db);
|
||||
links.push(format!("{}-db:{}", id, options.db.name()));
|
||||
env.push(format!("SQL={}", options.db.name()));
|
||||
}
|
||||
|
||||
let container = options
|
||||
.php
|
||||
.spawn(docker, &id, env, &network, links, volumes)
|
||||
.await
|
||||
.wrap_err("Failed to start php container")?;
|
||||
containers.push(container);
|
||||
|
||||
Ok(Cloud {
|
||||
id,
|
||||
network,
|
||||
containers,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn setup_workdir(base: &Utf8Path, id: &str) -> Result<()> {
|
||||
let workdir = base.join(id);
|
||||
create_dir_all(workdir.join("data")).await?;
|
||||
create_dir_all(workdir.join("config")).await?;
|
||||
create_dir_all(workdir.join("data-autotest")).await?;
|
||||
create_dir_all(workdir.join("skeleton")).await?;
|
||||
create_dir_all(workdir.join("integration/output")).await?;
|
||||
create_dir_all(workdir.join("integration/work")).await?;
|
||||
create_dir_all(workdir.join("integration/vendor")).await?;
|
||||
|
||||
write(workdir.join("integration/composer.lock"), "").await?;
|
||||
write(workdir.join("config/CAN_INSTALL"), "").await?;
|
||||
write(workdir.join("phpunit-cache"), "").await?;
|
||||
|
||||
create_dir_all(base.join("composer/cache")).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
6
src/config.rs
Normal file
6
src/config.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
use camino::Utf8PathBuf;
|
||||
|
||||
pub struct HazeConfig {
|
||||
pub sources_root: Utf8PathBuf,
|
||||
pub work_dir: Utf8PathBuf,
|
||||
}
|
||||
13
src/docker.rs
Normal file
13
src/docker.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
use color_eyre::Result;
|
||||
|
||||
pub struct Docker {
|
||||
handle: bollard::Docker,
|
||||
}
|
||||
|
||||
impl Docker {
|
||||
pub fn new() -> Result<Self> {
|
||||
Ok(Docker {
|
||||
handle: bollard::Docker::connect_with_local_defaults()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
14
src/main.rs
14
src/main.rs
|
|
@ -1,3 +1,15 @@
|
|||
use crate::config::HazeConfig;
|
||||
use camino::Utf8Path;
|
||||
use color_eyre::{eyre::WrapErr, Report, Result};
|
||||
use std::fs::create_dir_all;
|
||||
|
||||
mod cloud;
|
||||
mod config;
|
||||
mod docker;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
let config = HazeConfig {
|
||||
sources_root: "/srv/http/owncloud".into(),
|
||||
work_dir: "/tmp/oc-docket".into(),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue