Skip to content

Commit fb71e1e

Browse files
committed
system-reinstall-bootc: SSH key handling via cloud-init detection
If cloud-init is detected in the target image: 1. Check the host for existing root SSH keys at /root/.ssh/authorized_keys. 2. If host keys exist, automatically configure inheritance via /target/root/.ssh/authorized_keys. 3. If no host keys exist, proceed without manual interaction, trusting cloud-init in the new system to handle key provisioning. If cloud-init is not detected, maintain the existinginteractive behavior to prevent user lock-out. Ref: #1300 Signed-off-by: Terence Lee <hone02@gmail.com>
1 parent a095e34 commit fb71e1e

File tree

2 files changed

+52
-15
lines changed

2 files changed

+52
-15
lines changed

crates/system-reinstall-bootc/src/main.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,20 +110,36 @@ fn run() -> Result<()> {
110110
let has_clean = podman::bootc_has_clean(&opts.image)?;
111111
spinner.finish_and_clear();
112112

113-
let ssh_key_file = tempfile::NamedTempFile::new()?;
114-
let ssh_key_file_path = ssh_key_file
115-
.path()
116-
.to_str()
117-
.ok_or_else(|| anyhow::anyhow!("unable to create authorized_key temp file"))?;
113+
let mut _ssh_key_tempfile = None;
114+
let mut ssh_key_file_path = None;
115+
116+
if podman::image_has_cloud_init(&opts.image)? {
117+
let host_root_keys = std::path::Path::new("/root/.ssh/authorized_keys");
118+
if host_root_keys.exists() {
119+
println!("Detected cloud-init and host keys. Inheriting keys automatically.");
120+
ssh_key_file_path = Some("/target/root/.ssh/authorized_keys".to_string());
121+
} else {
122+
println!("Detected cloud-init. Proceeding without host key inheritance.");
123+
}
124+
} else {
125+
let file = tempfile::NamedTempFile::new()?;
126+
let file_path = file
127+
.path()
128+
.to_str()
129+
.ok_or_else(|| anyhow::anyhow!("unable to create authorized_key temp file"))?;
118130

119-
tracing::trace!("ssh_key_file_path: {}", ssh_key_file_path);
131+
tracing::trace!("ssh_key_file_path: {}", file_path);
120132

121-
prompt::get_ssh_keys(ssh_key_file_path)?;
133+
prompt::get_ssh_keys(file_path)?;
134+
135+
ssh_key_file_path = Some(file_path.to_string());
136+
_ssh_key_tempfile = Some(file);
137+
}
122138

123139
prompt::mount_warning()?;
124140

125141
let mut reinstall_podman_command =
126-
podman::reinstall_command(&opts, ssh_key_file_path, has_clean)?;
142+
podman::reinstall_command(&opts, ssh_key_file_path.as_deref(), has_clean)?;
127143

128144
println!();
129145
println!("Going to run command:");

crates/system-reinstall-bootc/src/podman.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
use crate::{ReinstallOpts, prompt};
1+
use crate::{prompt, ReinstallOpts};
22

33
use super::ROOT_KEY_MOUNT_POINT;
4-
use anyhow::{Context, Result, ensure};
4+
use anyhow::{ensure, Context, Result};
55
use bootc_utils::CommandRunExt;
66
use fn_error_context::context;
77
use std::process::Command;
@@ -24,10 +24,29 @@ pub(crate) fn bootc_has_clean(image: &str) -> Result<bool> {
2424
Ok(stdout_str.contains("--cleanup"))
2525
}
2626

27+
#[context("image_has_cloud_init")]
28+
pub(crate) fn image_has_cloud_init(image: &str) -> Result<bool> {
29+
let result = Command::new("podman")
30+
.args([
31+
"run",
32+
"--rm",
33+
"--entrypoint",
34+
"sh",
35+
image,
36+
"-c",
37+
"command -v cloud-init",
38+
])
39+
.stdout(std::process::Stdio::null())
40+
.stderr(std::process::Stdio::null())
41+
.status()?;
42+
43+
Ok(result.success())
44+
}
45+
2746
#[context("reinstall_command")]
2847
pub(crate) fn reinstall_command(
2948
opts: &ReinstallOpts,
30-
ssh_key_file: &str,
49+
ssh_key_file: Option<&str>,
3150
has_clean: bool,
3251
) -> Result<Command> {
3352
let mut podman_command_and_args = [
@@ -88,11 +107,13 @@ pub(crate) fn reinstall_command(
88107
bootc_command_and_args.push("--cleanup".to_string());
89108
}
90109

91-
podman_command_and_args.push("-v".to_string());
92-
podman_command_and_args.push(format!("{ssh_key_file}:{ROOT_KEY_MOUNT_POINT}"));
110+
if let Some(ssh_key_file) = ssh_key_file {
111+
podman_command_and_args.push("-v".to_string());
112+
podman_command_and_args.push(format!("{ssh_key_file}:{ROOT_KEY_MOUNT_POINT}"));
93113

94-
bootc_command_and_args.push("--root-ssh-authorized-keys".to_string());
95-
bootc_command_and_args.push(ROOT_KEY_MOUNT_POINT.to_string());
114+
bootc_command_and_args.push("--root-ssh-authorized-keys".to_string());
115+
bootc_command_and_args.push(ROOT_KEY_MOUNT_POINT.to_string());
116+
}
96117

97118
let all_args = [
98119
podman_command_and_args,

0 commit comments

Comments
 (0)