Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions cmux-tui/crates/cmux-host/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,18 +434,19 @@ fn cloud_verb(args: &[String]) -> u8 {
#[cfg(target_os = "linux")]
fn clone_mark(paths: &Paths) -> Result<serde_json::Value, String> {
use crate::cloud::client::Store;
use crate::cloud::clone_mark::{MARKER, copied, marker_text};
use crate::cloud::clone_mark::{copied, marker, marker_text};
let mut store = crate::cloud::role::FileStore::new(paths.clone());
let Some(copied) = copied(&store) else { return Ok(serde_json::json!({"marked": false})) };
let user = crate::linux::spawn::lookup_user(crate::daemon_spec::WORK_USER)
.ok_or("no work user on this machine")?;
let path = paths.at(MARKER);
let marker = marker();
let path = paths.at(&marker);
if let Some(dir) = path.parent() {
std::fs::create_dir_all(dir).map_err(|e| format!("{}: {e}", dir.display()))?;
std::os::unix::fs::lchown(dir, Some(user.uid), Some(user.gid))
.map_err(|e| format!("{}: {e}", dir.display()))?;
}
store.write(MARKER, &marker_text(&copied), 0o600)?;
store.write(&marker, &marker_text(&copied), 0o600)?;
std::os::unix::fs::lchown(&path, Some(user.uid), Some(user.gid))
.map_err(|e| format!("{}: {e}", path.display()))?;
Ok(serde_json::json!({"marked": true, "from": copied.from, "to": copied.to}))
Expand Down
12 changes: 10 additions & 2 deletions cmux-tui/crates/cmux-host/src/cloud/clone_mark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,16 @@
use super::client::Store;
use super::wire::{BIND_FILE, BOUND_FILE, Bound, parse_bind_file};

/// Where the marker goes, under the work user's acpmux home (`daemon_spec::WORK_HOME`).
pub const MARKER: &str = "/home/cmux/.acpmux/clone-boot";
/// The marker's name in the acpmux home (acpmux `hub/clone_boot.rs` `MARKER`).
pub const MARKER_NAME: &str = "clone-boot";

/// Where the marker goes: in the work user's acpmux home (`daemon_spec::WORK_HOME`), named by
/// `role::acpmux_home`, never a literal state root (`scripts/cmux-next/check-state-roots.sh`).
#[cfg(target_os = "linux")]
pub fn marker() -> String {
let home = super::role::acpmux_home(std::path::Path::new(crate::daemon_spec::WORK_HOME));
home.join(MARKER_NAME).to_string_lossy().into_owned()
}

/// A copy: the machine `bound.json` recorded and the one `bind.json` names now.
#[derive(Debug, PartialEq, Eq)]
Expand Down
8 changes: 7 additions & 1 deletion cmux-tui/crates/cmux-host/src/cloud/role.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,12 @@ impl Worker {
}
}

/// The acpmux home of the user whose home is `home`: the default `~/.acpmux`, as the image runs
/// acpmux. The one place cmux-host names it (the trajectory mirror, `clone_mark::marker`).
pub fn acpmux_home(home: &Path) -> PathBuf {
home.join(".acpmux")
}

/// Where the trajectory mirror finds acpmux: the work user's home when the
/// image has that user (the session host's layout, `linux/spawn.rs`
/// `select_layout`), else root's. Its staging folder for restores is that
Expand All @@ -1107,7 +1113,7 @@ fn spawn_trajectories(paths: &Paths) -> io::Result<Trajectories<PosterHttp>> {
}
std::os::unix::fs::lchown(&staging, Some(user.uid), Some(user.gid))?;
fs::set_permissions(&staging, fs::Permissions::from_mode(0o700))?;
let acpmux = home.join(".acpmux");
let acpmux = acpmux_home(&home);
let layout = Layout { sessions: acpmux.join("sessions"), home: home.clone(), staging };
let importer = AcpmuxImporter {
bin: binary_path(&home),
Expand Down
7 changes: 7 additions & 0 deletions cmux-tui/crates/cmux-host/tests/linux_agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,3 +511,10 @@ fn receiver_root_privileged_host_run_activates_native_bootstrap() {
}
println!("ROOT_BOUNDARY_EXECUTED native_host_run_activation");
}

/// `cloud clone-mark` writes acpmux's marker where acpmux reads it: `clone-boot` in the work
/// user's `~/.acpmux` (#33140). The path comes from `role::acpmux_home`, not a literal root.
#[test]
fn clone_mark_writes_in_the_work_users_acpmux_home() {
assert_eq!(cmux_host::cloud::clone_mark::marker(), "/home/cmux/.acpmux/clone-boot");
}
Loading