1
0
Fork 0
mirror of https://codeberg.org/icewind/haze.git synced 2026-06-03 17:14:08 +02:00

add option to mount app packages

This commit is contained in:
Robin Appelman 2021-07-06 15:57:36 +02:00
commit acfbdd16d9
4 changed files with 106 additions and 1 deletions

57
Cargo.lock generated
View file

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3
[[package]] [[package]]
name = "addr2line" name = "addr2line"
version = "0.14.1" version = "0.14.1"
@ -188,6 +190,15 @@ dependencies = [
"tracing-error", "tracing-error",
] ]
[[package]]
name = "crc32fast"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "ct-logs" name = "ct-logs"
version = "0.8.0" version = "0.8.0"
@ -288,6 +299,30 @@ dependencies = [
"once_cell", "once_cell",
] ]
[[package]]
name = "filetime"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"winapi",
]
[[package]]
name = "flate2"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0"
dependencies = [
"cfg-if",
"crc32fast",
"libc",
"miniz_oxide",
]
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@ -409,6 +444,7 @@ dependencies = [
"camino", "camino",
"color-eyre", "color-eyre",
"directories-next", "directories-next",
"flate2",
"futures-util", "futures-util",
"maplit", "maplit",
"opener", "opener",
@ -416,6 +452,7 @@ dependencies = [
"petname", "petname",
"reqwest", "reqwest",
"serde", "serde",
"tar",
"termion", "termion",
"tokio", "tokio",
"toml", "toml",
@ -1101,6 +1138,17 @@ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]]
name = "tar"
version = "0.4.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d779dc6aeff029314570f666ec83f19df7280bb36ef338442cfa8c604021b80"
dependencies = [
"filetime",
"libc",
"xattr",
]
[[package]] [[package]]
name = "termion" name = "termion"
version = "1.5.6" version = "1.5.6"
@ -1463,3 +1511,12 @@ checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
dependencies = [ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "xattr"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
dependencies = [
"libc",
]

View file

@ -19,6 +19,8 @@ directories-next = "2"
serde = "1" serde = "1"
petname = "1" petname = "1"
reqwest = { version = "0.11", default-features = false } reqwest = { version = "0.11", default-features = false }
tar = "0.4"
flate2 = "1"
[profile.release] [profile.release]
lto = true lto = true

View file

@ -29,6 +29,10 @@ haze start [database] [php-version]
Where `database` is one of `sqlite`, `mysql`, `mariadb` or `pgsql` with an optional version (e.g. `pgsql:12`), defaults to `sqlite`. Where `database` is one of `sqlite`, `mysql`, `mariadb` or `pgsql` with an optional version (e.g. `pgsql:12`), defaults to `sqlite`.
And `php-version` is one of `7.2`, `7.3`, `7.4`, `8.0`, `7` or `8`, defaults to `8.0` And `php-version` is one of `7.2`, `7.3`, `7.4`, `8.0`, `7` or `8`, defaults to `8.0`
Additionally, you can use the following options when starting an instance:
- `s3`: setup Nextcloud with S3 primary storage
- `<path to app.tar.gz>`: by specifying the path to an app package this package will be extracted into the apps directory of the new instance (overwriting any existing app code). This can be used to quickly test a packaged app.
#### Run tests in a new instance #### Run tests in a new instance
```bash ```bash

View file

@ -1,4 +1,4 @@
use crate::config::HazeConfig; use crate::config::{HazeConfig, HazeVolumeConfig};
use crate::database::Database; use crate::database::Database;
use crate::exec::{exec, exec_tty, ExitCode}; use crate::exec::{exec, exec_tty, ExitCode};
use crate::mapping::{default_mappings, Mapping}; use crate::mapping::{default_mappings, Mapping};
@ -10,6 +10,7 @@ use bollard::network::CreateNetworkOptions;
use bollard::Docker; use bollard::Docker;
use camino::Utf8PathBuf; use camino::Utf8PathBuf;
use color_eyre::{eyre::WrapErr, Report, Result}; use color_eyre::{eyre::WrapErr, Report, Result};
use flate2::read::GzDecoder;
use futures_util::future::try_join_all; use futures_util::future::try_join_all;
use petname::petname; use petname::petname;
use std::collections::HashMap; use std::collections::HashMap;
@ -21,6 +22,7 @@ use std::net::IpAddr;
use std::os::unix::fs::MetadataExt; use std::os::unix::fs::MetadataExt;
use std::str::FromStr; use std::str::FromStr;
use std::time::Duration; use std::time::Duration;
use tokio::fs::create_dir_all;
use tokio::fs::remove_dir_all; use tokio::fs::remove_dir_all;
use tokio::task::spawn; use tokio::task::spawn;
use tokio::time::sleep; use tokio::time::sleep;
@ -30,6 +32,7 @@ pub struct CloudOptions {
db: Database, db: Database,
php: PhpVersion, php: PhpVersion,
services: Vec<Service>, services: Vec<Service>,
app_packages: Vec<Utf8PathBuf>,
} }
impl CloudOptions { impl CloudOptions {
@ -41,6 +44,7 @@ impl CloudOptions {
let mut db = None; let mut db = None;
let mut php = None; let mut php = None;
let mut services = Vec::new(); let mut services = Vec::new();
let mut app_package = Vec::new();
while let Some(option) = args.peek() { while let Some(option) = args.peek() {
if let Ok(db_option) = Database::from_str(option.as_ref()) { if let Ok(db_option) = Database::from_str(option.as_ref()) {
@ -52,6 +56,9 @@ impl CloudOptions {
} else if let Some(service) = Service::from_type(option.as_ref()) { } else if let Some(service) = Service::from_type(option.as_ref()) {
services.extend_from_slice(service); services.extend_from_slice(service);
let _ = args.next(); let _ = args.next();
} else if option.as_ref().ends_with(".tar.gz") {
app_package.push(option.to_string().into());
let _ = args.next();
} else { } else {
break; break;
} }
@ -61,6 +68,7 @@ impl CloudOptions {
db: db.unwrap_or_default(), db: db.unwrap_or_default(),
php: php.unwrap_or_default(), php: php.unwrap_or_default(),
services, services,
app_packages: app_package,
}) })
} }
} }
@ -149,11 +157,45 @@ impl Cloud {
let id = format!("haze-{}", petname(2, "-")); let id = format!("haze-{}", petname(2, "-"));
let workdir = config.work_dir.join(&id); let workdir = config.work_dir.join(&id);
let app_package_dir = workdir.join("app_package");
if !options.app_packages.is_empty() {
create_dir_all(&app_package_dir)
.await
.wrap_err("Failed to create directory for app packages")?;
}
let app_volumes = options
.app_packages
.into_iter()
.map(|app_package| {
let app_name = app_package.file_name().unwrap().trim_end_matches(".tar.gz");
let app_dir = app_package_dir.join(app_name);
let app_package_file = fs::File::open(&app_package)
.wrap_err_with(|| format!("Failed to open app bundle {}", app_package))?;
if app_package.metadata()?.len() > 1024 * 1024 {
println!("Extracting app archive for {}...", app_name);
}
let gz = GzDecoder::new(app_package_file);
tar::Archive::new(gz)
.unpack(&app_package_dir)
.wrap_err_with(|| format!("Failed to extract app bundle {}", app_package))?;
Ok(HazeVolumeConfig {
create: false,
source: app_dir,
read_only: true,
target: format!("/var/www/html/apps/{}", app_name).into(),
})
})
.collect::<Result<Vec<_>>>()?;
let mappings = config let mappings = config
.volume .volume
.iter() .iter()
.map(Mapping::from) .map(Mapping::from)
.chain(default_mappings()) .chain(default_mappings())
.chain(app_volumes.iter().map(Mapping::from))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
for mapping in &mappings { for mapping in &mappings {
mapping mapping