Prepare, configure, and manage Firecracker microVMs in seconds!
virtualization
linux
microvm
firecracker
1use anyhow::Result;
2
3use crate::command::{run_command, run_command_with_stdout_inherit};
4
5pub fn generate_and_copy_ssh_key(key_name: &str, squashfs_root_dir: &str) -> Result<()> {
6 let app_dir = crate::config::get_config_dir()?;
7
8 if std::path::Path::new(&format!("{}/{}", app_dir, key_name)).exists() {
9 println!(
10 "[!] Warning: {} already exists, skipping key generation.",
11 key_name
12 );
13 let pub_key_path = format!("{}/{}.pub", app_dir, key_name);
14 let auth_keys_path = format!("{}/root/.ssh/authorized_keys", squashfs_root_dir);
15 run_command(
16 "mkdir",
17 &["-p", &format!("{}/root/.ssh", squashfs_root_dir)],
18 true,
19 )?;
20 run_command("cp", &[&pub_key_path, &auth_keys_path], true)?;
21 return Ok(());
22 }
23
24 let key_name = format!("{}/{}", app_dir, key_name);
25 run_command_with_stdout_inherit("ssh-keygen", &["-f", &key_name, "-N", ""], false)?;
26
27 let pub_key_path = format!("{}.pub", key_name);
28 let auth_keys_path = format!("{}/root/.ssh/authorized_keys", squashfs_root_dir);
29 run_command("cp", &[&pub_key_path, &auth_keys_path], true)?;
30 Ok(())
31}
32
33pub fn generate_and_copy_ssh_key_nixos(key_name: &str, squashfs_root_dir: &str) -> Result<String> {
34 let app_dir = crate::config::get_config_dir()?;
35 const DEFAULT_SSH: &str = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAR4Gvuv3lTpXIYeZTRO22nVEj64uMmlDAdt5+GG80hm tsiry@tsiry-XPS-9320";
36
37 if std::path::Path::new(&format!("{}/{}", app_dir, key_name)).exists() {
38 println!(
39 "[!] Warning: {} already exists, skipping key generation.",
40 key_name
41 );
42 let pub_key_path = format!("{}/{}.pub", app_dir, key_name);
43 let nixos_configuration = format!("{}/etc/nixos/configuration.nix", squashfs_root_dir);
44 let public_key = std::fs::read_to_string(&pub_key_path)
45 .map_err(|e| anyhow::anyhow!("Failed to read public key: {}", e))?
46 .trim()
47 .to_string();
48 run_command(
49 "sed",
50 &[
51 "-i",
52 &format!("s|{}|{}|", DEFAULT_SSH, public_key),
53 &nixos_configuration,
54 ],
55 true,
56 )?;
57
58 run_command(
59 "mkdir",
60 &["-p", &format!("{}/root/.ssh", squashfs_root_dir)],
61 true,
62 )?;
63 run_command(
64 "cp",
65 &[
66 &pub_key_path,
67 &format!("{}/root/.ssh/authorized_keys", squashfs_root_dir),
68 ],
69 true,
70 )?;
71
72 return Ok(public_key);
73 }
74
75 let key_name = format!("{}/{}", app_dir, key_name);
76 run_command_with_stdout_inherit("ssh-keygen", &["-f", &key_name, "-N", ""], false)?;
77
78 let pub_key_path = format!("{}.pub", key_name);
79 let nixos_configuration = format!("{}/etc/nixos/configuration.nix", squashfs_root_dir);
80 let public_key = std::fs::read_to_string(&pub_key_path)
81 .map_err(|e| anyhow::anyhow!("Failed to read public key: {}", e))?
82 .trim()
83 .to_string();
84 run_command(
85 "sed",
86 &[
87 "-i",
88 &format!("s|{}|{}|", DEFAULT_SSH, public_key),
89 &nixos_configuration,
90 ],
91 true,
92 )?;
93
94 run_command(
95 "mkdir",
96 &["-p", &format!("{}/root/.ssh", squashfs_root_dir)],
97 true,
98 )?;
99 run_command(
100 "cp",
101 &[
102 &pub_key_path,
103 &format!("{}/root/.ssh/authorized_keys", squashfs_root_dir),
104 ],
105 true,
106 )?;
107
108 Ok(public_key)
109}
110
111pub fn copy_ssh_keys(ssh_keys: &[String], squashfs_root_dir: &str) -> Result<()> {
112 run_command(
113 "mkdir",
114 &["-p", &format!("{}/root/.ssh", squashfs_root_dir)],
115 true,
116 )?;
117
118 let auth_keys_path = "/tmp/authorized_keys";
119 let mut auth_keys_file = std::fs::OpenOptions::new()
120 .create(true)
121 .append(true)
122 .open(&auth_keys_path)
123 .map_err(|e| anyhow::anyhow!("Failed to open authorized_keys file: {}", e))?;
124
125 for key in ssh_keys {
126 use std::io::Write;
127 writeln!(auth_keys_file, "{}", key)
128 .map_err(|e| anyhow::anyhow!("Failed to write to authorized_keys file: {}", e))?;
129 }
130
131 run_command(
132 "cp",
133 &[
134 &auth_keys_path,
135 &format!("{}/root/.ssh/authorized_keys", squashfs_root_dir),
136 ],
137 true,
138 )?;
139 std::fs::remove_file(&auth_keys_path)
140 .map_err(|e| anyhow::anyhow!("Failed to remove temporary authorized_keys file: {}", e))?;
141
142 Ok(())
143}