mirror of
https://github.com/robcholz/vibebox.git
synced 2026-10-10 01:03:56 +02:00
fix: now project dir correctly mounted
This commit is contained in:
1 parent
9cf33359f9
commit
5659f2a538
5 files changed
+55
-15
No files matched your search
+1
-1
@@ -46,7 +46,7 @@ fn default_mounts(cwd: &Path) -> Result<Vec<tui::MountListRow>, Box<dyn Error +
|
|||||||
.file_name()
|
.file_name()
|
||||||
.and_then(|name| name.to_str())
|
.and_then(|name| name.to_str())
|
||||||
.unwrap_or("project");
|
.unwrap_or("project");
|
||||||
let project_guest = format!("/root/{project_name}");
|
let project_guest = format!("~/{project_name}");
|
||||||
let project_host = display_path(cwd);
|
let project_host = display_path(cwd);
|
||||||
let mut rows = vec![tui::MountListRow {
|
let mut rows = vec![tui::MountListRow {
|
||||||
host: project_host,
|
host: project_host,
|
||||||
|
|||||||
@@ -394,6 +394,7 @@ fn ssh_port_open(ip: &str) -> bool {
|
|||||||
pub(crate) fn build_ssh_login_actions(
|
pub(crate) fn build_ssh_login_actions(
|
||||||
config: &Arc<Mutex<InstanceConfig>>,
|
config: &Arc<Mutex<InstanceConfig>>,
|
||||||
project_name: &str,
|
project_name: &str,
|
||||||
|
project_guest_dir: &str,
|
||||||
guest_dir: &str,
|
guest_dir: &str,
|
||||||
key_name: &str,
|
key_name: &str,
|
||||||
home_links_script: &str,
|
home_links_script: &str,
|
||||||
@@ -409,6 +410,7 @@ pub(crate) fn build_ssh_login_actions(
|
|||||||
.replace("__SSH_USER__", &ssh_user)
|
.replace("__SSH_USER__", &ssh_user)
|
||||||
.replace("__SUDO_PASSWORD__", &sudo_password)
|
.replace("__SUDO_PASSWORD__", &sudo_password)
|
||||||
.replace("__PROJECT_NAME__", project_name)
|
.replace("__PROJECT_NAME__", project_name)
|
||||||
|
.replace("__PROJECT_GUEST_DIR__", project_guest_dir)
|
||||||
.replace("__KEY_PATH__", &key_path)
|
.replace("__KEY_PATH__", &key_path)
|
||||||
.replace("__VIBEBOX_SHELL_SCRIPT__", &commands::render_shell_script())
|
.replace("__VIBEBOX_SHELL_SCRIPT__", &commands::render_shell_script())
|
||||||
.replace("__VIBEBOX_HOME_LINKS__", home_links_script);
|
.replace("__VIBEBOX_HOME_LINKS__", home_links_script);
|
||||||
|
|||||||
+17
-1
@@ -3,6 +3,7 @@ set -eu
|
|||||||
|
|
||||||
SSH_USER="__SSH_USER__"
|
SSH_USER="__SSH_USER__"
|
||||||
PROJECT_NAME="__PROJECT_NAME__"
|
PROJECT_NAME="__PROJECT_NAME__"
|
||||||
|
PROJECT_GUEST_DIR="__PROJECT_GUEST_DIR__"
|
||||||
KEY_PATH="__KEY_PATH__"
|
KEY_PATH="__KEY_PATH__"
|
||||||
|
|
||||||
diag() { echo "[vibebox][diag] $*" >&2; }
|
diag() { echo "[vibebox][diag] $*" >&2; }
|
||||||
@@ -49,7 +50,7 @@ dump_diag() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# 1) tmpfs mount
|
# 1) tmpfs mount
|
||||||
TARGET="/root/${PROJECT_NAME}/.vibebox"
|
TARGET="${PROJECT_GUEST_DIR}/.vibebox"
|
||||||
if [ -d "$TARGET" ] && ! mountpoint -q "$TARGET"; then
|
if [ -d "$TARGET" ] && ! mountpoint -q "$TARGET"; then
|
||||||
mount -t tmpfs tmpfs "$TARGET"
|
mount -t tmpfs tmpfs "$TARGET"
|
||||||
fi
|
fi
|
||||||
@@ -78,6 +79,21 @@ __VIBEBOX_SHELL_SCRIPT__
|
|||||||
VIBEBOX_SHELL_EOF
|
VIBEBOX_SHELL_EOF
|
||||||
chmod 644 /etc/profile.d/vibebox.sh
|
chmod 644 /etc/profile.d/vibebox.sh
|
||||||
|
|
||||||
|
# Auto-cd into project for interactive shells
|
||||||
|
cat > /etc/profile.d/vibebox-project.sh <<'VIBEBOX_PROJECT_EOF'
|
||||||
|
case "$-" in
|
||||||
|
*i*)
|
||||||
|
project_home="${HOME}/__PROJECT_NAME__"
|
||||||
|
if [ "$USER" = "__SSH_USER__" ] && [ -d "$project_home" ]; then
|
||||||
|
cd "$project_home"
|
||||||
|
elif [ "$USER" = "__SSH_USER__" ] && [ -d "__PROJECT_GUEST_DIR__" ]; then
|
||||||
|
cd "__PROJECT_GUEST_DIR__"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
VIBEBOX_PROJECT_EOF
|
||||||
|
chmod 644 /etc/profile.d/vibebox-project.sh
|
||||||
|
|
||||||
if ! grep -q "vibebox-aliases" "${USER_HOME}/.bashrc" 2>/dev/null; then
|
if ! grep -q "vibebox-aliases" "${USER_HOME}/.bashrc" 2>/dev/null; then
|
||||||
{
|
{
|
||||||
echo ""
|
echo ""
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ const DEBIAN_COMPRESSED_DISK_URL: &str = "https://cloud.debian.org/images/cloud/
|
|||||||
const DEBIAN_COMPRESSED_SHA: &str = "6ab9be9e6834adc975268367f2f0235251671184345c34ee13031749fdfbf66fe4c3aafd949a2d98550426090e9ac645e79009c51eb0eefc984c15786570bb38";
|
const DEBIAN_COMPRESSED_SHA: &str = "6ab9be9e6834adc975268367f2f0235251671184345c34ee13031749fdfbf66fe4c3aafd949a2d98550426090e9ac645e79009c51eb0eefc984c15786570bb38";
|
||||||
const DEBIAN_COMPRESSED_SIZE_BYTES: u64 = 280901576;
|
const DEBIAN_COMPRESSED_SIZE_BYTES: u64 = 280901576;
|
||||||
const SHARED_DIRECTORIES_TAG: &str = "shared";
|
const SHARED_DIRECTORIES_TAG: &str = "shared";
|
||||||
|
pub const PROJECT_GUEST_BASE: &str = "/usr/local/vibebox-mounts";
|
||||||
|
|
||||||
const BYTES_PER_MB: u64 = 1024 * 1024;
|
const BYTES_PER_MB: u64 = 1024 * 1024;
|
||||||
const DEFAULT_CPU_COUNT: usize = 2;
|
const DEFAULT_CPU_COUNT: usize = 2;
|
||||||
@@ -247,7 +248,8 @@ where
|
|||||||
let mut directory_shares = Vec::new();
|
let mut directory_shares = Vec::new();
|
||||||
|
|
||||||
if !args.no_default_mounts {
|
if !args.no_default_mounts {
|
||||||
login_actions.push(Send(format!("cd {project_name}")));
|
let project_guest_dir = PathBuf::from(PROJECT_GUEST_BASE).join(project_name);
|
||||||
|
login_actions.push(Send(format!("cd {}", project_guest_dir.display())));
|
||||||
|
|
||||||
// discourage read/write of .git folder from within the VM. note that this isn't secure, since the VM runs as root and could unmount this.
|
// discourage read/write of .git folder from within the VM. note that this isn't secure, since the VM runs as root and could unmount this.
|
||||||
// I couldn't find an alternative way to do this --- the MacOS sandbox doesn't apply to the Apple Virtualization system
|
// I couldn't find an alternative way to do this --- the MacOS sandbox doesn't apply to the Apple Virtualization system
|
||||||
@@ -255,15 +257,6 @@ where
|
|||||||
login_actions.push(Send(r"mount -t tmpfs tmpfs .git/".into()));
|
login_actions.push(Send(r"mount -t tmpfs tmpfs .git/".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
directory_shares.push(
|
|
||||||
DirectoryShare::new(
|
|
||||||
project_root,
|
|
||||||
PathBuf::from("/root/").join(project_name),
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
.expect("Project directory must exist"),
|
|
||||||
);
|
|
||||||
|
|
||||||
directory_shares.push(mise_directory_share);
|
directory_shares.push(mise_directory_share);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+32
-3
@@ -25,7 +25,7 @@ use crate::{
|
|||||||
session_manager::{
|
session_manager::{
|
||||||
GLOBAL_DIR_NAME, INSTANCE_FILENAME, VM_MANAGER_PID_NAME, VM_MANAGER_SOCKET_NAME,
|
GLOBAL_DIR_NAME, INSTANCE_FILENAME, VM_MANAGER_PID_NAME, VM_MANAGER_SOCKET_NAME,
|
||||||
},
|
},
|
||||||
vm::{self, DirectoryShare, LoginAction, VmInput},
|
vm::{self, DirectoryShare, LoginAction, PROJECT_GUEST_BASE, VmInput},
|
||||||
};
|
};
|
||||||
|
|
||||||
const VM_MANAGER_LOCK_NAME: &str = "vm.lock";
|
const VM_MANAGER_LOCK_NAME: &str = "vm.lock";
|
||||||
@@ -200,6 +200,30 @@ fn cleanup_stale_manager(instance_dir: &Path) {
|
|||||||
let _ = fs::remove_file(&pid_path);
|
let _ = fs::remove_file(&pid_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn inject_project_mount(
|
||||||
|
mounts: &mut Vec<String>,
|
||||||
|
project_root: &Path,
|
||||||
|
ssh_user: &str,
|
||||||
|
project_name: &str,
|
||||||
|
) {
|
||||||
|
let guest_tilde = format!("~/{project_name}");
|
||||||
|
let guest_home = format!("/home/{ssh_user}/{project_name}");
|
||||||
|
let guest_base = format!("{PROJECT_GUEST_BASE}/{project_name}");
|
||||||
|
let already_mapped = mounts.iter().any(|spec| {
|
||||||
|
let parts: Vec<&str> = spec.split(':').collect();
|
||||||
|
if parts.len() < 2 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let guest = parts[1];
|
||||||
|
guest == guest_tilde || guest == guest_home || guest == guest_base
|
||||||
|
});
|
||||||
|
if already_mapped {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let host = project_root.display();
|
||||||
|
mounts.insert(0, format!("{host}:{guest_tilde}:read-write"));
|
||||||
|
}
|
||||||
|
|
||||||
fn is_socket_path(path: &Path) -> bool {
|
fn is_socket_path(path: &Path) -> bool {
|
||||||
fs::metadata(path)
|
fs::metadata(path)
|
||||||
.map(|meta| meta.file_type().is_socket())
|
.map(|meta| meta.file_type().is_socket())
|
||||||
@@ -252,7 +276,7 @@ fn rewrite_mount_spec(spec: &str, ssh_user: &str) -> (String, Option<HomeLink>)
|
|||||||
return (spec.to_string(), None);
|
return (spec.to_string(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let root_base = "/usr/local/vibebox-mounts";
|
let root_base = PROJECT_GUEST_BASE;
|
||||||
let root_path = if rel.is_empty() {
|
let root_path = if rel.is_empty() {
|
||||||
root_base.to_string()
|
root_base.to_string()
|
||||||
} else {
|
} else {
|
||||||
@@ -563,7 +587,7 @@ impl VmExecutor for RealVmExecutor {
|
|||||||
|
|
||||||
fn run_manager_with(
|
fn run_manager_with(
|
||||||
project_root: &Path,
|
project_root: &Path,
|
||||||
args: vm::VmArg,
|
mut args: vm::VmArg,
|
||||||
auto_shutdown_ms: u64,
|
auto_shutdown_ms: u64,
|
||||||
executor: &dyn VmExecutor,
|
executor: &dyn VmExecutor,
|
||||||
options: ManagerOptions,
|
options: ManagerOptions,
|
||||||
@@ -602,8 +626,12 @@ fn run_manager_with(
|
|||||||
.lock()
|
.lock()
|
||||||
.map(|cfg| cfg.ssh_user_display())
|
.map(|cfg| cfg.ssh_user_display())
|
||||||
.unwrap_or_else(|_| DEFAULT_SSH_USER.to_string());
|
.unwrap_or_else(|_| DEFAULT_SSH_USER.to_string());
|
||||||
|
if !args.no_default_mounts {
|
||||||
|
inject_project_mount(&mut args.mounts, project_root, &ssh_user, &project_name);
|
||||||
|
}
|
||||||
let (args, home_links_script) = prepare_mounts_and_links(args, &ssh_user);
|
let (args, home_links_script) = prepare_mounts_and_links(args, &ssh_user);
|
||||||
|
|
||||||
|
let project_guest_dir = format!("{PROJECT_GUEST_BASE}/{project_name}");
|
||||||
let ssh_guest_dir = format!("/root/{}", GLOBAL_DIR_NAME);
|
let ssh_guest_dir = format!("/root/{}", GLOBAL_DIR_NAME);
|
||||||
let extra_shares = vec![DirectoryShare::new(
|
let extra_shares = vec![DirectoryShare::new(
|
||||||
instance_dir.clone(),
|
instance_dir.clone(),
|
||||||
@@ -613,6 +641,7 @@ fn run_manager_with(
|
|||||||
let extra_login_actions = build_ssh_login_actions(
|
let extra_login_actions = build_ssh_login_actions(
|
||||||
&config,
|
&config,
|
||||||
&project_name,
|
&project_name,
|
||||||
|
&project_guest_dir,
|
||||||
ssh_guest_dir.as_str(),
|
ssh_guest_dir.as_str(),
|
||||||
"ssh_key",
|
"ssh_key",
|
||||||
&home_links_script,
|
&home_links_script,
|
||||||
|
|||||||
Reference in new issue
Block a user