Skip to content

Support kata container runtime - #84

Merged
vsilent merged 6 commits into
trydirect:masterfrom
vsilent:support-kata-container-runtime
Apr 8, 2026
Merged

vsilent merged 6 commits into
trydirect:masterfrom
vsilent:support-kata-container-runtime

Conversation

@vsilent

@vsilent vsilent commented Apr 7, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

vsilent and others added 5 commits March 30, 2026 13:39
- Validate stack_id to prevent path traversal in marketplace deploy
- Return proper HTTP status codes (502/504) on marketplace proxy errors
- Replace blocking std::fs with tokio::fs in link_page and unlink_handler
- Fix deployStack() to show stack name instead of ID in confirmation modal
- Add rel="noopener noreferrer" to target="_blank" links

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 7, 2026 11:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Kata Containers runtime selection support to the agent deploy flow, including capability discovery and compose runtime injection, alongside a couple of UI/security and async I/O improvements.

Changes:

  • Introduce ContainerRuntime (runc/kata) for deploy commands, inject runtime into compose YAML, and return effective runtime in deploy results.
  • Expose Kata support via /capabilities when detected.
  • UI/security tweaks: fix marketplace deploy modal naming, add rel="noopener noreferrer" to external links, and harden marketplace deploy stack_id validation; convert link/unlink filesystem ops to async.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
TODO.md Documents intended “Kata Containers Support” follow-ups for Stacker/CLI/UI.
templates/marketplace.html Uses the correct stack card to display the stack name in the deploy modal.
templates/link.html Adds rel="noopener noreferrer" and updates the signup link URL.
src/comms/local_api.rs Adds Kata feature detection in /capabilities, improves marketplace error status propagation, validates stack_id, and switches link/unlink file I/O to tokio FS.
src/commands/stacker.rs Adds runtime enum + compose runtime injection + deploy output fields, and accompanying unit tests.

Comment thread src/commands/stacker.rs Outdated
);
}

#[cfg(test)]

Copilot AI Apr 7, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

runtime_compose_tests is only gated by #[cfg(test)], but it calls inject_runtime_into_compose, which is compiled only when feature = "docker" is enabled. CI runs cargo test --no-default-features --features minimal, so this module will fail to compile under the minimal feature set. Gate this test module with #[cfg(all(test, feature = "docker"))] (or provide a non-docker stub) so minimal builds/tests pass.

Suggested change
#[cfg(test)]
#[cfg(all(test, feature = "docker"))]

Copilot uses AI. Check for mistakes.
Comment thread src/commands/stacker.rs Outdated
Comment on lines +2721 to +2747
if *runtime == ContainerRuntime::Kata && std::path::Path::new(&compose_file).exists() {
let kata_available = detect_kata_runtime().await;
if kata_available {
if let Ok(existing) = tokio::fs::read_to_string(&compose_file).await {
let injected = inject_runtime_into_compose(&existing, runtime);
if let Err(e) = tokio::fs::write(&compose_file, &injected).await {
errors.push(make_error(
"runtime_inject_warning",
format!("Failed to inject Kata runtime into compose file: {}", e),
None,
));
} else {
tracing::info!(
compose_file = %compose_file,
"Injected Kata runtime into existing compose file"
);
}
}
} else {
tracing::warn!(
"Kata runtime requested but not available on this host — falling back to runc"
);
errors.push(make_error(
"kata_fallback",
"Kata runtime requested but not available on this host; deploying with runc",
None,
));

Copilot AI Apr 7, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This async handler uses std::path::Path::exists() to check for the compose file. That call is blocking and can stall the Tokio runtime under load. Prefer tokio::fs::try_exists(...).await (or tokio::fs::metadata) so the runtime injection path remains non-blocking.

Suggested change
if *runtime == ContainerRuntime::Kata && std::path::Path::new(&compose_file).exists() {
let kata_available = detect_kata_runtime().await;
if kata_available {
if let Ok(existing) = tokio::fs::read_to_string(&compose_file).await {
let injected = inject_runtime_into_compose(&existing, runtime);
if let Err(e) = tokio::fs::write(&compose_file, &injected).await {
errors.push(make_error(
"runtime_inject_warning",
format!("Failed to inject Kata runtime into compose file: {}", e),
None,
));
} else {
tracing::info!(
compose_file = %compose_file,
"Injected Kata runtime into existing compose file"
);
}
}
} else {
tracing::warn!(
"Kata runtime requested but not available on this host — falling back to runc"
);
errors.push(make_error(
"kata_fallback",
"Kata runtime requested but not available on this host; deploying with runc",
None,
));
if *runtime == ContainerRuntime::Kata {
match tokio::fs::try_exists(&compose_file).await {
Ok(true) => {
let kata_available = detect_kata_runtime().await;
if kata_available {
if let Ok(existing) = tokio::fs::read_to_string(&compose_file).await {
let injected = inject_runtime_into_compose(&existing, runtime);
if let Err(e) = tokio::fs::write(&compose_file, &injected).await {
errors.push(make_error(
"runtime_inject_warning",
format!("Failed to inject Kata runtime into compose file: {}", e),
None,
));
} else {
tracing::info!(
compose_file = %compose_file,
"Injected Kata runtime into existing compose file"
);
}
}
} else {
tracing::warn!(
"Kata runtime requested but not available on this host — falling back to runc"
);
errors.push(make_error(
"kata_fallback",
"Kata runtime requested but not available on this host; deploying with runc",
None,
));
}
}
Ok(false) => {}
Err(e) => {
errors.push(make_error(
"runtime_inject_warning",
format!("Failed to check compose file before runtime injection: {}", e),
None,
));
}

Copilot uses AI. Check for mistakes.
Comment thread src/comms/local_api.rs
Comment on lines +937 to +942
// Detect Kata Containers runtime availability
#[cfg(feature = "docker")]
{
if crate::commands::stacker::detect_kata_runtime().await {
features.push("kata".to_string());
}

Copilot AI Apr 7, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/capabilities shells out to docker info on every request via detect_kata_runtime(). If Docker is slow/unavailable, this can add noticeable latency or hang the endpoint (there’s no timeout in detect_kata_runtime). Consider caching the detection result (e.g., OnceLock + refresh interval) and/or wrapping the detection call in a short tokio::time::timeout so /capabilities remains responsive.

Copilot uses AI. Check for mistakes.
Comment thread src/comms/local_api.rs Outdated
Comment on lines +1236 to +1238
let reg_path = "/etc/status-panel/registration.json";
if tokio::fs::try_exists(reg_path).await.unwrap_or(false) {
if let Err(e) = tokio::fs::remove_file(reg_path).await {

Copilot AI Apr 7, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try_exists(...).await.unwrap_or(false) suppresses any underlying IO error (e.g., permission issues) and silently behaves like “not linked”. Logging the error path would make unlink failures diagnosable (especially on read-only /etc or permission mismatches).

Copilot uses AI. Check for mistakes.
- Gate runtime_compose_tests with #[cfg(all(test, feature = "docker"))]
- Replace blocking Path::exists() with tokio::fs::try_exists() in deploy
- Cache detect_kata_runtime() with OnceLock + 5s timeout
- Log errors in unlink_handler try_exists path
- Bump version to 0.1.6
- Update CHANGELOG

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@vsilent
vsilent merged commit 4b53c85 into trydirect:master Apr 8, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants