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

allow exec'ing service containers

This commit is contained in:
Robin Appelman 2026-06-03 15:28:25 +02:00
commit d138740bbd
7 changed files with 74 additions and 16 deletions

View file

@ -151,11 +151,14 @@ haze [match] db
#### Execute a command on an instance
```bash
haze [match] exec [cmd]
haze [match] [service] [cmd]
```
If no `cmd` is specified it will launch `bash`
If a service name or `db` is provided, the command will be in the container of
the service or database.
#### Create a new instance and run a command
```bash

View file

@ -165,6 +165,7 @@ impl LogService {
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum ExecService {
Db,
Service(Service),
}
impl HazeArgs {
@ -232,6 +233,14 @@ impl HazeArgs {
args.next();
Some(ExecService::Db)
}
Some(arg) => Service::from_type(&[], arg.as_ref())
.into_iter()
.filter_map(|services| services.into_iter().next())
.next()
.map(|service| {
args.next();
ExecService::Service(service)
}),
_ => None,
};

View file

@ -148,6 +148,9 @@ async fn main() -> Result<ExitCode> {
root,
} => {
let cloud = Cloud::get_by_filter(&docker, filter, &config).await?;
let env = get_forward_env();
let tty = atty::is(atty::Stream::Stdout);
match service {
None => {
let command = if command.is_empty() {
@ -155,8 +158,7 @@ async fn main() -> Result<ExitCode> {
} else {
command
};
let env = get_forward_env();
let tty = atty::is(atty::Stream::Stdout);
let user = if root { "root" } else { "haze" };
if tty {
exec_tty(&docker, &cloud.id, user, command, env).await?;
@ -165,19 +167,42 @@ async fn main() -> Result<ExitCode> {
}
}
Some(ExecService::Db) => {
cloud
.db()
.exec_sh(
&docker,
&cloud.id,
if command.is_empty() {
let command = if command.is_empty() {
vec!["bash".to_string()]
} else {
command
},
atty::is(atty::Stream::Stdout),
)
.await?;
};
cloud.db().exec_sh(&docker, &cloud.id, command, tty).await?;
}
Some(ExecService::Service(service)) => {
let Some(container) = service.container_name(&cloud.id) else {
eprintln!(
"Service {} can't be exec'ed as it has no associated container",
service.name()
);
return Ok(ExitCode::FAILURE);
};
if service.exec_shell() == "" && command.is_empty() {
eprintln!(
"Service {} can't be exec'ed as it has no shell",
service.name()
);
return Ok(ExitCode::FAILURE);
}
let command = if command.is_empty() {
vec![service.exec_shell().to_string()]
} else {
command
};
let user = if root { "root" } else { service.exec_user() };
if tty {
exec_tty(&docker, &container, user, command, env).await?;
} else {
exec(&docker, &container, user, command, env, Some(stdout())).await?;
}
}
}
}

View file

@ -194,6 +194,14 @@ pub trait ServiceTrait {
fn proxy_port(&self) -> u16 {
80
}
fn exec_user(&self) -> &'static str {
"root"
}
fn exec_shell(&self) -> &'static str {
"bash"
}
}
#[derive(Clone, Eq, PartialEq, Debug)]
@ -242,6 +250,7 @@ pub enum ServiceType {
/// Ldap admin interface
LdapAdmin,
/// OnlyOffice
#[strum(serialize = "onlyoffice", serialize = "only-office")]
OnlyOffice,
/// Libre office online
Office,

View file

@ -75,4 +75,8 @@ impl ServiceTrait for Redis {
"occ config:system:set redis host --value redis",
)])
}
fn exec_shell(&self) -> &'static str {
"sh"
}
}

View file

@ -90,4 +90,8 @@ impl ServiceTrait for Smb {
split_cmnd("occ files_external:config 1 share test"),
])
}
fn exec_shell(&self) -> &'static str {
"sh"
}
}

View file

@ -68,4 +68,8 @@ impl ServiceTrait for Webhook {
fn proxy_port(&self) -> u16 {
8080
}
fn exec_shell(&self) -> &'static str {
""
}
}