From 158d1bbbb4ae6ebdc7dad94fb5480eca1e0e565a Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 29 Apr 2021 09:02:51 +0300 Subject: [PATCH] Don't create temp dir under current dir in 'zenith init'. Previously, 'zenith init' would initialize a PostgreSQL cluster with "initdb -D tmp", creating the temp cluster under current directory. It moves the 'tmp' directory under the correct snapshot directory in the zenith repository after that, but if something goes wrong in initdb, or in the steps that follow, it could leave behind the 'tmp' directory under current dir. Better to create the temporary directory under the repository directory to begin with, as ".zenith/tmp". --- control_plane/src/local_env.rs | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/control_plane/src/local_env.rs b/control_plane/src/local_env.rs index efbabc0211..d8331f7dfb 100644 --- a/control_plane/src/local_env.rs +++ b/control_plane/src/local_env.rs @@ -129,12 +129,13 @@ pub fn init_repo(local_env: &mut LocalEnv) -> Result<()> { // Run initdb // - // FIXME: we create it temporarily in "tmp" directory, and move it into - // the repository. Use "tempdir()" or something? Or just create it directly - // in the repo? + // We create the cluster temporarily in a "tmp" directory inside the repository, + // and move it to the right location from there. + let tmppath = repopath.join("tmp"); + let initdb_path = local_env.pg_bin_dir().join("initdb"); let initdb = Command::new(initdb_path) - .args(&["-D", "tmp"]) + .args(&["-D", tmppath.to_str().unwrap()]) .arg("--no-instructions") .env_clear() .env("LD_LIBRARY_PATH", local_env.pg_lib_dir().to_str().unwrap()) @@ -151,15 +152,17 @@ pub fn init_repo(local_env: &mut LocalEnv) -> Result<()> { println!("initdb succeeded"); // Read control file to extract the LSN and system id - let controlfile = - postgres_ffi::decode_pg_control(Bytes::from(fs::read("tmp/global/pg_control")?))?; + let controlfile_path = tmppath.join("global").join("pg_control"); + let controlfile = postgres_ffi::decode_pg_control(Bytes::from(fs::read(controlfile_path)?))?; let systemid = controlfile.system_identifier; let lsn = controlfile.checkPoint; let lsnstr = format!("{:016X}", lsn); // Move the initial WAL file fs::rename( - "tmp/pg_wal/000000010000000000000001", + tmppath + .join("pg_wal") + .join("000000010000000000000001"), timelinedir .join("wal") .join("000000010000000000000001.partial"), @@ -167,14 +170,13 @@ pub fn init_repo(local_env: &mut LocalEnv) -> Result<()> { println!("moved initial WAL file"); // Remove pg_wal - fs::remove_dir_all("tmp/pg_wal")?; - println!("removed tmp/pg_wal"); + fs::remove_dir_all(tmppath.join("pg_wal"))?; - force_crash_recovery(&PathBuf::from("tmp"))?; + force_crash_recovery(&tmppath)?; println!("updated pg_control"); let target = timelinedir.join("snapshots").join(&lsnstr); - fs::rename("tmp", &target)?; + fs::rename(tmppath, &target)?; println!("moved 'tmp' to {}", target.display()); // Create 'main' branch to refer to the initial timeline