Precheck docker availability and drop unused ContainerSession.image_tag
Surfaces a clean DockerUnavailable error when docker mode is requested
but the daemon isn't reachable, replacing the cryptic "command not
found" stderr that bubbled out of docker_build. Drops the unused
image_tag field on ContainerSession — the tag is already tracked on
ContainerRecord.
Assisted-by: Claude Opus 4.7 via Claude Code
diff --git a/src/ci/docker.rs b/src/ci/docker.rs
index 23bd38d..040d46c 100644
--- a/src/ci/docker.rs
+++ b/src/ci/docker.rs
@@ -50,7 +50,6 @@ pub(crate) fn docker_build(dockerfile: &Path, context: &Path, tag: &str) -> Resu
/// reconciliation handles anything that survives.
pub(crate) struct ContainerSession {
pub(crate) container_id: String,
- pub(crate) image_tag: String,
pub(crate) container_started_at: jiff::Timestamp,
}
@@ -89,7 +88,6 @@ impl ContainerSession {
let container_id = String::from_utf8_lossy(&output.stdout).trim().to_string();
Ok(Self {
container_id,
- image_tag: image_tag.to_string(),
container_started_at: jiff::Timestamp::now(),
})
}
@@ -172,7 +170,6 @@ mod tests {
assert!(!session.container_id.is_empty());
// Docker container IDs from `docker run` are 64-char SHA256 hex.
assert_eq!(session.container_id.len(), 64, "got: {}", session.container_id);
- assert_eq!(session.image_tag, "alpine:3.19");
// session drops here; docker stop runs.
}
diff --git a/src/ci/run.rs b/src/ci/run.rs
index 46c6a92..150f7e3 100644
--- a/src/ci/run.rs
+++ b/src/ci/run.rs
@@ -444,6 +444,10 @@ impl Run {
match executor {
Executor::Host => Ok(ExecutorRuntime::Host),
Executor::Docker => {
+ if !crate::ci::docker::is_available() {
+ return Err(Error::DockerUnavailable);
+ }
+
let mut record = ContainerRecord::default();
// Build phase.
diff --git a/src/error.rs b/src/error.rs
index 80478b1..3702f9b 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -40,6 +40,9 @@ pub enum Error {
source: Box<Error>,
},
+ #[error("docker is not available — install docker and ensure the daemon is running")]
+ DockerUnavailable,
+
#[error("workspace materialization failed")]
WorkspaceMaterializationFailed {
#[source]