1
0
Fork 0
mirror of https://codeberg.org/icewind/haze.git synced 2026-06-03 09:04:12 +02:00

cleanup mapping handling

This commit is contained in:
Robin Appelman 2021-03-18 18:52:08 +01:00
commit a6b0e8fde1
3 changed files with 165 additions and 65 deletions

View file

@ -1,12 +1,13 @@
use crate::config::HazeConfig;
use crate::database::Database;
use crate::exec::{exec, exec_tty};
use crate::mapping::default_mappings;
use crate::php::PhpVersion;
use bollard::container::{ListContainersOptions, LogsOptions, RemoveContainerOptions};
use bollard::models::ContainerState;
use bollard::network::CreateNetworkOptions;
use bollard::Docker;
use camino::{Utf8Path, Utf8PathBuf};
use camino::Utf8PathBuf;
use color_eyre::{eyre::WrapErr, Report, Result};
use futures_util::stream::StreamExt;
use petname::petname;
@ -19,7 +20,7 @@ use std::net::IpAddr;
use std::os::unix::fs::MetadataExt;
use std::str::FromStr;
use std::time::Duration;
use tokio::fs::{create_dir_all, remove_dir_all, write};
use tokio::fs::remove_dir_all;
use tokio::time::sleep;
#[derive(Clone, Default, Debug, Eq, PartialEq)]
@ -120,9 +121,14 @@ impl Cloud {
) -> Result<Self> {
let id = format!("haze-{}", petname(2, "-"));
let workdir = setup_workdir(&config.work_dir, &id)
.await
.wrap_err("Failed to setup work directories")?;
let workdir = config.work_dir.join(&id);
let mappings = default_mappings();
for mapping in &mappings {
mapping
.create(&id, config)
.await
.wrap_err_with(|| format!("Failed to setup work directory {}", mapping.source))?;
}
let network = docker
.create_network(CreateNetworkOptions {
@ -146,47 +152,10 @@ impl Cloud {
format!("GID={}", gid),
format!("SQL={}", options.db.name()),
];
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.sources_root
),
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
),
];
let volumes = mappings
.into_iter()
.filter_map(|mapping| mapping.get_volume_arg(&id, config))
.collect();
if let Some(db_name) = options
.db
@ -409,22 +378,3 @@ impl Cloud {
Ok(())
}
}
async fn setup_workdir(base: &Utf8Path, id: &str) -> Result<Utf8PathBuf> {
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(workdir)
}

View file

@ -10,6 +10,7 @@ mod config;
mod database;
mod exec;
mod image;
mod mapping;
mod php;
#[tokio::main]

149
src/mapping.rs Normal file
View file

@ -0,0 +1,149 @@
use crate::config::HazeConfig;
use camino::Utf8Path;
use color_eyre::Result;
use tokio::fs::{create_dir_all, write};
#[derive(Debug)]
pub struct Mapping<'a> {
source_type: MappingSourceType,
pub source: &'a Utf8Path,
target: &'a Utf8Path,
mapping_type: MappingType,
read_only: bool,
map: bool,
}
impl<'a> Mapping<'a> {
pub fn new<Source, Target>(
source_type: MappingSourceType,
source: Source,
target: Target,
) -> Self
where
Target: Into<&'a Utf8Path>,
Source: Into<&'a Utf8Path>,
{
Mapping {
source_type,
source: source.into(),
target: target.into(),
mapping_type: MappingType::Folder,
read_only: false,
map: true,
}
}
pub fn read_only(self) -> Self {
Self {
read_only: true,
..self
}
}
pub fn dont_map(self) -> Self {
Self { map: false, ..self }
}
pub fn file(self) -> Self {
Self {
mapping_type: MappingType::File,
..self
}
}
pub async fn create(&self, id: &str, config: &HazeConfig) -> Result<()> {
let source = match self.source_type {
MappingSourceType::WorkDir => config.work_dir.join(id).join(self.source),
MappingSourceType::GlobalWorkDir => config.work_dir.join(self.source),
MappingSourceType::Sources => return Ok(()),
};
match self.mapping_type {
MappingType::Folder => create_dir_all(source).await?,
MappingType::File => write(source, "").await?,
}
Ok(())
}
pub fn get_volume_arg(&self, id: &str, config: &HazeConfig) -> Option<String> {
if !self.map {
return None;
}
let source = match self.source_type {
MappingSourceType::WorkDir => config.work_dir.join(id).join(self.source),
MappingSourceType::GlobalWorkDir => config.work_dir.join(self.source),
MappingSourceType::Sources => config.sources_root.join(self.source),
};
Some(if self.read_only {
format!("{}:{}:ro", source, self.target)
} else {
format!("{}:{}", source, self.target)
})
}
}
pub fn default_mappings() -> Vec<Mapping<'static>> {
use MappingSourceType::*;
vec![
Mapping::new(Sources, "", "/var/www/html"),
Mapping::new(WorkDir, "data", "/var/www/html/data"),
Mapping::new(WorkDir, "config", "/var/www/html/config"),
Mapping::new(WorkDir, "data-autotest", "/var/www/html/data-autotest"),
Mapping::new(WorkDir, "skeleton", "/var/www/html/core/skeleton"),
Mapping::new(
Sources,
"skeleton/welcome.txt",
"/var/www/html/core/skeleton/welcome.txt",
)
.file()
.read_only(),
Mapping::new(
WorkDir,
"integration/vendor",
"/var/www/html/build/integration/vendor",
),
Mapping::new(
WorkDir,
"integration/work",
"/var/www/html/build/integration/work",
),
Mapping::new(
WorkDir,
"integration/output",
"/var/www/html/build/integration/output",
),
Mapping::new(
WorkDir,
"integration/composer.lock",
"/var/www/html/build/integration/composer.lock",
)
.file(),
Mapping::new(GlobalWorkDir, "composer/cache", "/var/www/.composer/cache"),
Mapping::new(
GlobalWorkDir,
"phpunit-cache",
"/var/www/html/tests/.phpunit.result.cache",
)
.file(),
Mapping::new(WorkDir, "config/CAN_INSTALL", "")
.file()
.dont_map(),
Mapping::new(Sources, ".htaccess", "/var/www/html/.htaccess")
.file()
.read_only(),
]
}
#[derive(Debug, Copy, Clone)]
pub enum MappingSourceType {
Sources,
WorkDir,
GlobalWorkDir,
}
#[derive(Debug, Copy, Clone)]
pub enum MappingType {
Folder,
File,
}