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

add command to update images

This commit is contained in:
Robin Appelman 2025-08-26 17:13:18 +02:00
commit 85335d84de
5 changed files with 93 additions and 44 deletions

View file

@ -209,6 +209,12 @@ environment variables set for the matched instance.
This is indented to run a local
[push daemon](https://github.com/nextcloud/notify_push) against an instance.
#### Update the container images
```bash
haze update
```
## Federation
Multiple instances can reach each other by using their instance name as domain

View file

@ -73,6 +73,8 @@ pub enum HazeArgs {
command: String,
args: Vec<String>,
},
/// Update docker images
Update,
}
#[derive(Debug, Clone, Eq, PartialEq)]
@ -266,6 +268,7 @@ impl HazeArgs {
args: args.collect(),
})
}
HazeCommand::Update => Ok(HazeArgs::Update),
}
}
}
@ -290,6 +293,7 @@ pub enum HazeCommand {
Proxy,
Checkout,
Env,
Update,
}
impl FromStr for HazeCommand {
@ -316,6 +320,7 @@ impl FromStr for HazeCommand {
"proxy" => Ok(HazeCommand::Proxy),
"checkout" => Ok(HazeCommand::Checkout),
"env" => Ok(HazeCommand::Env),
"update" => Ok(HazeCommand::Update),
_ => Err(Report::msg(format!("Unknown command: {}", s))),
}
}
@ -342,6 +347,7 @@ impl HazeCommand {
HazeCommand::Proxy => false,
HazeCommand::Checkout => false,
HazeCommand::Env => true,
HazeCommand::Update => false,
}
}
}

View file

@ -12,55 +12,65 @@ pub async fn image_exists(docker: &Docker, image: &str) -> bool {
docker.inspect_image(image).await.is_ok()
}
pub async fn update_image(docker: &Docker, image: &str) -> Result<()> {
if image_exists(docker, image).await {
force_pull_image(docker, image).await?;
}
Ok(())
}
pub async fn pull_image(docker: &Docker, image: &str) -> Result<()> {
if docker.inspect_image(image).await.is_err() {
println!("Pulling image {}", image);
if !image_exists(docker, image).await {
force_pull_image(docker, image).await?;
}
Ok(())
}
let mut info_stream = docker.create_image(
Some(CreateImageOptions {
from_image: if image.contains(':') {
image.to_string()
} else {
format!("{}:latest", image)
},
..Default::default()
}),
None,
None,
);
pub async fn force_pull_image(docker: &Docker, image: &str) -> Result<()> {
println!("Pulling image {}", image);
let mut bars: HashMap<String, u16> = HashMap::new();
let mut info_stream = docker.create_image(
Some(CreateImageOptions {
from_image: if image.contains(':') {
image.to_string()
} else {
format!("{}:latest", image)
},
..Default::default()
}),
None,
None,
);
let mut stdout = stdout();
while let Some(info) = info_stream.next().await {
let info: CreateImageInfo = info
.into_diagnostic()
.wrap_err_with(|| format!("Error while pulling image {}", image))?;
if let (Some(id), Some(status), Some(progress)) = (info.id, info.status, info.progress)
{
match bars.get(&id) {
Some(pos) => {
let offset = bars.len() as u16 - pos;
write!(
stdout,
"{}{}{} - {:12} {}{}",
cursor::Save,
cursor::Up(offset),
id,
status,
progress,
cursor::Restore
)
.into_diagnostic()?;
}
None => {
writeln!(stdout, "{} - {:12} {}", id, status, progress)
.into_diagnostic()?;
bars.insert(id, bars.len() as u16);
}
let mut bars: HashMap<String, u16> = HashMap::new();
let mut stdout = stdout();
while let Some(info) = info_stream.next().await {
let info: CreateImageInfo = info
.into_diagnostic()
.wrap_err_with(|| format!("Error while pulling image {}", image))?;
if let (Some(id), Some(status), Some(progress)) = (info.id, info.status, info.progress) {
match bars.get(&id) {
Some(pos) => {
let offset = bars.len() as u16 - pos;
write!(
stdout,
"{}{}{} - {:12} {}{}",
cursor::Save,
cursor::Up(offset),
id,
status,
progress,
cursor::Restore
)
.into_diagnostic()?;
}
None => {
writeln!(stdout, "{} - {:12} {}", id, status, progress).into_diagnostic()?;
bars.insert(id, bars.len() as u16);
}
stdout.flush().into_diagnostic()?;
}
stdout.flush().into_diagnostic()?;
}
}
Ok(())

View file

@ -6,7 +6,9 @@ use crate::config::HazeConfig;
use crate::database::DatabaseFamily;
use crate::exec::container_logs;
use crate::git::checkout_all;
use crate::image::update_image;
use crate::network::clear_networks;
use crate::php::PhpVersion;
use crate::proxy::proxy;
use crate::service::ServiceTrait;
use crate::service::{RedisTls, Service};
@ -436,6 +438,11 @@ async fn main() -> Result<ExitCode> {
let err = command.exec();
return Err(err).into_diagnostic();
}
HazeArgs::Update => {
for php in PhpVersion::all() {
update_image(&docker, php.image()).await?;
}
}
};
Ok(ExitCode::SUCCESS)

View file

@ -67,7 +67,7 @@ impl FromStr for PhpVersion {
}
impl PhpVersion {
fn image(&self) -> &'static str {
pub fn image(&self) -> &'static str {
// for now only 7.4
match self {
PhpVersion::Php73 => "icewind1991/haze:7.3",
@ -127,6 +127,26 @@ impl PhpVersion {
}
}
pub fn all() -> impl Iterator<Item = Self> {
[
PhpVersion::Php73,
PhpVersion::Php74,
PhpVersion::Php80,
PhpVersion::Php81,
PhpVersion::Php82,
PhpVersion::Php83,
PhpVersion::Php84,
PhpVersion::Php73Dbg,
PhpVersion::Php74Dbg,
PhpVersion::Php80Dbg,
PhpVersion::Php81Dbg,
PhpVersion::Php82Dbg,
PhpVersion::Php83Dbg,
PhpVersion::Php84Dbg,
]
.into_iter()
}
#[allow(clippy::too_many_arguments)]
pub async fn spawn(
&self,