Skip to content

Commit

Permalink
compute tmpfiles inside atomically write functions
Browse files Browse the repository at this point in the history
Signed-off-by: Krzysztof Piotrowski <Krzysztof.Piotrowski@inetum.com>
  • Loading branch information
Ruadhri17 committed Apr 20, 2023
1 parent cbc5840 commit bb2dcb2
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ use camino::Utf8PathBuf;

pub const DEFAULT_TEDGE_CONFIG_PATH: &str = "/etc/tedge";
const TEDGE_CONFIG_FILE: &str = "tedge.toml";
const TEDGE_CONFIG_FILE_TMP: &str = "tedge.toml.tmp";

/// Information about where `tedge.toml` is located.
///
/// Broadly speaking, we distinguish two different locations:
Expand Down Expand Up @@ -49,10 +47,6 @@ impl TEdgeConfigLocation {
pub fn tedge_config_file_path(&self) -> &Utf8Path {
&self.tedge_config_file_path
}

pub fn temporary_tedge_config_file_path(&self) -> Utf8PathBuf {
self.tedge_config_root_path.join(TEDGE_CONFIG_FILE_TMP)
}
}

#[test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ impl TEdgeConfigRepository {
}

atomically_write_file_sync(
self.config_location.temporary_tedge_config_file_path(),
self.config_location.tedge_config_file_path(),
toml.as_bytes(),
)?;
Expand Down
29 changes: 14 additions & 15 deletions crates/common/tedge_utils/src/fs.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
use std::fs as std_fs;
use std::io::Write;
use std::path::Path;
use std::path::PathBuf;

use tokio::fs as tokio_fs;
use tokio::io::AsyncWriteExt;

/// Write file to filesystem atomically using std::fs synchronously.
pub fn atomically_write_file_sync(
tempfile: impl AsRef<Path>,
dest: impl AsRef<Path>,
content: &[u8],
) -> std::io::Result<()> {
pub fn atomically_write_file_sync(dest: impl AsRef<Path>, content: &[u8]) -> std::io::Result<()> {
let mut tempfile = PathBuf::from(dest.as_ref());
tempfile.set_extension("tmp");

let mut file = std_fs::OpenOptions::new()
.write(true)
.create_new(true)
.open(tempfile.as_ref())?;
.open(&tempfile)?;

if let Err(err) = file.write_all(content) {
let _ = std_fs::remove_file(tempfile);
Expand All @@ -23,7 +23,7 @@ pub fn atomically_write_file_sync(

file.flush()?;

if let Err(err) = std_fs::rename(tempfile.as_ref(), dest) {
if let Err(err) = std_fs::rename(&tempfile, dest) {
let _ = std_fs::remove_file(tempfile);
return Err(err);
}
Expand All @@ -33,14 +33,16 @@ pub fn atomically_write_file_sync(

/// Write file to filesystem atomically using tokio::fs asynchronously.
pub async fn atomically_write_file_async(
tempfile: impl AsRef<Path>,
dest: impl AsRef<Path>,
content: &[u8],
) -> std::io::Result<()> {
let mut tempfile = PathBuf::from(dest.as_ref());
tempfile.set_extension("tmp");

let mut file = tokio_fs::OpenOptions::new()
.write(true)
.create_new(true)
.open(tempfile.as_ref())
.open(&tempfile)
.await?;

if let Err(err) = file.write_all(content).await {
Expand All @@ -50,7 +52,7 @@ pub async fn atomically_write_file_async(

file.flush().await?;

if let Err(err) = tokio_fs::rename(tempfile.as_ref(), dest).await {
if let Err(err) = tokio_fs::rename(&tempfile, dest).await {
tokio_fs::remove_file(tempfile).await?;
return Err(err);
}
Expand All @@ -73,7 +75,7 @@ mod tests {

let content = "test_data";

atomically_write_file_async(&temp_path, &destination_path, content.as_bytes())
atomically_write_file_async(&destination_path, content.as_bytes())
.await
.unwrap();

Expand All @@ -88,15 +90,12 @@ mod tests {
#[test]
fn atomically_write_file_file_sync() {
let temp_dir = tempdir().unwrap();
let temp_path = temp_dir.path().join("test1");
let destination_path = temp_dir.path().join("test2");

let content = "test_data";

let () =
atomically_write_file_sync(&temp_path, &destination_path, content.as_bytes()).unwrap();
let () = atomically_write_file_sync(&destination_path, content.as_bytes()).unwrap();

std::fs::File::open(&temp_path).unwrap_err();
if let Ok(destination_content) = std::fs::read(&destination_path) {
assert_eq!(destination_content, content.as_bytes());
} else {
Expand Down
6 changes: 1 addition & 5 deletions crates/core/tedge_agent/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,7 @@ impl StateRepository for AgentStateRepository {
fs::create_dir(&self.state_repo_root).await?;
}

let mut temppath = self.state_repo_path.clone();
temppath.set_extension("tmp");

let () =
atomically_write_file_async(temppath, &self.state_repo_path, toml.as_bytes()).await?;
let () = atomically_write_file_async(&self.state_repo_path, toml.as_bytes()).await?;

Ok(())
}
Expand Down

0 comments on commit bb2dcb2

Please sign in to comment.