mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-07-26 07:30:19 +00:00
kata-deploy: install kata-ctl on the node when debug is enabled
kata-ctl provides `kata-ctl exec <sandbox-id>`, the runtime-rs entry point into a sandbox's agent debug console. It ships in the kata-tools bundle rather than with the shim binaries, so it is not staged into the kata-deploy image and never lands on the node - leaving runtime-rs deployments without a first-class way to reach the debug console. Signed-off-by: Fabiano Fidêncio <ffidencio@nvidia.com> Assisted-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
10
.github/workflows/publish-kata-images.yaml
vendored
10
.github/workflows/publish-kata-images.yaml
vendored
@@ -119,6 +119,16 @@ jobs:
|
||||
path: tools/packaging/kata-deploy/local-build/build
|
||||
merge-multiple: true
|
||||
|
||||
# kata-ctl ships in the kata-tools bundle under its own artifact name, so
|
||||
# stage it into the build dir separately to bake it into the deploy image.
|
||||
- name: get-kata-ctl for ${{ inputs.arch }}
|
||||
if: ${{ inputs.artifact-name == '' && matrix.image-kind == 'deploy' }}
|
||||
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||
with:
|
||||
pattern: kata-tools-artifacts-${{ inputs.arch }}-kata-ctl${{ inputs.tarball-suffix }}
|
||||
path: tools/packaging/kata-deploy/local-build/build
|
||||
merge-multiple: true
|
||||
|
||||
- name: get-kata-static-tarball for ${{ inputs.arch }}
|
||||
if: ${{ inputs.artifact-name == '' && matrix.image-kind == 'monitor' }}
|
||||
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||
|
||||
@@ -107,6 +107,9 @@ pub async fn install_artifacts(config: &Config, container_runtime: &str) -> Resu
|
||||
|
||||
let mut extracted: HashSet<String> = HashSet::new();
|
||||
extract_component_tarballs(config, &mut extracted)?;
|
||||
// Not tied to any shim, so reconcile separately: turning debug off on a
|
||||
// redeploy must also remove it.
|
||||
reconcile_debug_tools(config, &mut extracted)?;
|
||||
install_versions_yaml(config)?;
|
||||
|
||||
set_executable_permissions(&config.host_install_dir)?;
|
||||
@@ -741,6 +744,106 @@ fn extract_component_tarballs(config: &Config, extracted: &mut HashSet<String>)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Debug-only tools pulled in by the debug flag rather than per-shim membership:
|
||||
/// kata-ctl ships in the kata-tools bundle, not with the shims.
|
||||
const DEBUG_TOOL_COMPONENTS: &[&str] = &["kata-ctl"];
|
||||
|
||||
/// Static list of a tool's installed files, needed to remove it when debug is
|
||||
/// off: nothing is extracted then, so paths can't be discovered dynamically.
|
||||
fn debug_tool_paths(component: &str) -> &'static [&'static str] {
|
||||
match component {
|
||||
"kata-ctl" => &["bin/kata-ctl"],
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
|
||||
/// Extract debug tooling when debug is on, remove it when off so a redeploy
|
||||
/// never leaves it behind. Extraction is best-effort: a missing tarball only
|
||||
/// warns, since an image may be built without the tools.
|
||||
fn reconcile_debug_tools(config: &Config, extracted: &mut HashSet<String>) -> Result<()> {
|
||||
if config.debug {
|
||||
extract_debug_tools_in(
|
||||
DEBUG_TOOL_COMPONENTS,
|
||||
Path::new(TARBALLS_DIR),
|
||||
&config.host_install_dir,
|
||||
true,
|
||||
extracted,
|
||||
)
|
||||
} else {
|
||||
remove_debug_tools_in(DEBUG_TOOL_COMPONENTS, Path::new(&config.host_install_dir));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove the given debug tools' files. Best-effort and idempotent: only
|
||||
/// existing files are touched and a failed removal warns instead of aborting.
|
||||
fn remove_debug_tools_in(components: &[&str], install_dir: &Path) {
|
||||
for component in components {
|
||||
for rel in debug_tool_paths(component) {
|
||||
let path = install_dir.join(rel);
|
||||
if path.exists() {
|
||||
info!(
|
||||
"debug disabled: removing debug tool '{}' ({})",
|
||||
component,
|
||||
path.display()
|
||||
);
|
||||
if let Err(e) = fs::remove_file(&path) {
|
||||
log::warn!("debug: failed to remove {}: {}", path.display(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Testable core of the debug-tool extraction: takes explicit paths so it can
|
||||
/// be unit tested without the container image layout.
|
||||
fn extract_debug_tools_in(
|
||||
components: &[&str],
|
||||
tarballs_dir: &Path,
|
||||
host_install_dir: &str,
|
||||
debug: bool,
|
||||
extracted: &mut HashSet<String>,
|
||||
) -> Result<()> {
|
||||
if !debug {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
for component in components {
|
||||
if extracted.contains(*component) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let tarball_name = format!("kata-static-{}.tar.zst", component);
|
||||
let tarball_path = tarballs_dir.join(&tarball_name);
|
||||
|
||||
if !tarball_path.exists() {
|
||||
log::warn!(
|
||||
"debug: optional tool '{}' not found at {}; skipping. Rebuild the \
|
||||
kata-deploy image with the '{}' component to enable it.",
|
||||
component,
|
||||
tarball_path.display(),
|
||||
component
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
info!("debug: extracting optional tool '{}'", component);
|
||||
if let Err(e) = extract_tarball(&tarball_path, host_install_dir) {
|
||||
log::warn!(
|
||||
"debug: failed to extract optional tool '{}' from {}: {:#}; skipping",
|
||||
component,
|
||||
tarball_path.display(),
|
||||
e
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
extracted.insert((*component).to_string());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_executable_permissions(dir: &str) -> Result<()> {
|
||||
let bin_paths = ["bin", "runtime-rs/bin"];
|
||||
|
||||
@@ -1656,4 +1759,76 @@ mod tests {
|
||||
fs::remove_dir_all(&runtime_dir).unwrap();
|
||||
assert!(!runtime_dir.exists());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extract_debug_tools_disabled_is_noop() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let dest = tmp.path().to_str().unwrap();
|
||||
let mut extracted: HashSet<String> = HashSet::new();
|
||||
|
||||
extract_debug_tools_in(&["kata-ctl"], tmp.path(), dest, false, &mut extracted).unwrap();
|
||||
|
||||
assert!(extracted.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extract_debug_tools_missing_tarball_is_best_effort() {
|
||||
let tarballs = tempfile::tempdir().unwrap();
|
||||
let dest = tempfile::tempdir().unwrap();
|
||||
let mut extracted: HashSet<String> = HashSet::new();
|
||||
|
||||
extract_debug_tools_in(
|
||||
&["kata-ctl"],
|
||||
tarballs.path(),
|
||||
dest.path().to_str().unwrap(),
|
||||
true,
|
||||
&mut extracted,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(extracted.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extract_debug_tools_skips_already_extracted() {
|
||||
let tarballs = tempfile::tempdir().unwrap();
|
||||
let dest = tempfile::tempdir().unwrap();
|
||||
let mut extracted: HashSet<String> = ["kata-ctl".to_string()].into_iter().collect();
|
||||
|
||||
extract_debug_tools_in(
|
||||
&["kata-ctl"],
|
||||
tarballs.path(),
|
||||
dest.path().to_str().unwrap(),
|
||||
true,
|
||||
&mut extracted,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(extracted.len(), 1);
|
||||
assert!(extracted.contains("kata-ctl"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_debug_tools_removes_installed_files() {
|
||||
let install = tempfile::tempdir().unwrap();
|
||||
let bin = install.path().join("bin");
|
||||
fs::create_dir_all(&bin).unwrap();
|
||||
let kata_ctl = bin.join("kata-ctl");
|
||||
fs::write(&kata_ctl, "binary").unwrap();
|
||||
// A sibling that must be left untouched.
|
||||
let shim = bin.join("containerd-shim-kata-v2");
|
||||
fs::write(&shim, "shim").unwrap();
|
||||
|
||||
remove_debug_tools_in(&["kata-ctl"], install.path());
|
||||
|
||||
assert!(!kata_ctl.exists(), "kata-ctl removed when debug is off");
|
||||
assert!(shim.exists(), "unrelated binaries untouched");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_remove_debug_tools_is_noop_when_absent() {
|
||||
let install = tempfile::tempdir().unwrap();
|
||||
remove_debug_tools_in(&["kata-ctl"], install.path());
|
||||
assert!(!install.path().join("bin/kata-ctl").exists());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user