Skip to content

Commit a2fb368

Browse files
committed
agent: Call backup hooks
1 parent e869dd1 commit a2fb368

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

guest-agent/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ fs-err.workspace = true
1515
rcgen.workspace = true
1616
sha2.workspace = true
1717
clap.workspace = true
18-
tokio.workspace = true
18+
tokio = { workspace = true, features = ["full"] }
1919
hex.workspace = true
2020
serde_json.workspace = true
2121
bollard.workspace = true

guest-agent/src/guest_api_service.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::fmt::Debug;
22

3-
use anyhow::{Context, Result};
3+
use anyhow::{bail, Context, Result};
44
use bollard::{container::ListContainersOptions, Docker};
55
use cmd_lib::{run_cmd as cmd, run_fun};
66
use dstack_guest_agent_rpc::worker_server::WorkerRpc as _;
@@ -122,15 +122,48 @@ impl GuestApiRpc for GuestApiHandler {
122122
.write(true)
123123
.open(BACKUP_LOCK_FILE)
124124
.context("Failed to create backup lock file, there is another backup in progress")?;
125+
// Run /dstack/hooks/pre-backup if it exists
126+
let pre_backup_hook = "/dstack/hooks/pre-backup";
127+
if is_exe(pre_backup_hook) {
128+
let status = tokio::process::Command::new(pre_backup_hook)
129+
.spawn()
130+
.context("Failed to run pre-backup hook")?
131+
.wait()
132+
.await
133+
.context("Failed to run pre-backup hook")?;
134+
if !status.success() {
135+
bail!("Failed to run pre-backup hook");
136+
}
137+
}
125138
Ok(())
126139
}
127140

128141
async fn post_backup(self) -> Result<()> {
129142
fs::remove_file(BACKUP_LOCK_FILE).context("Failed to remove backup lock file")?;
143+
let post_backup_hook = "/dstack/hooks/post-backup";
144+
if is_exe(post_backup_hook) {
145+
let status = tokio::process::Command::new(post_backup_hook)
146+
.spawn()
147+
.context("Failed to run post-backup hook")?
148+
.wait()
149+
.await
150+
.context("Failed to run post-backup hook")?;
151+
if !status.success() {
152+
bail!("Failed to run post-backup hook");
153+
}
154+
}
130155
Ok(())
131156
}
132157
}
133158

159+
fn is_exe(path: &str) -> bool {
160+
use std::os::unix::fs::PermissionsExt;
161+
let Ok(metadata) = fs::metadata(path) else {
162+
return false;
163+
};
164+
metadata.is_file() && metadata.permissions().mode() & 0o111 != 0
165+
}
166+
134167
pub(crate) async fn list_containers() -> Result<ListContainersResponse> {
135168
let docker = Docker::connect_with_defaults().context("Failed to connect to Docker")?;
136169
let containers = docker

0 commit comments

Comments
 (0)