Skip to content

Commit

Permalink
static-pods: write manifest to tempfile before persisting it
Browse files Browse the repository at this point in the history
When writing static pod manifest, create them as temporary files and
finish writing to them before persisting them in the destination file
path.
  • Loading branch information
etungsten committed Mar 24, 2021
1 parent f81034e commit bf996cb
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 9 deletions.
1 change: 1 addition & 0 deletions sources/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions sources/api/static-pods/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ snafu = "0.6"
tokio = { version = "0.2", default-features = false, features = ["macros", "rt-threaded"] }
# When we update hyper to 0.14+ which has tokio 1:
#tokio = { version = "1", default-features = false, features = ["macros", "rt-multi-thread", "time"] }
tempfile = "3.2.0"

[build-dependencies]
cargo-readme = "3.1"
51 changes: 42 additions & 9 deletions sources/api/static-pods/src/static_pods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,23 @@ It queries for all existing static pod settings, then configures the system as f
* If the pod is disabled, it ensures the manifest file is removed from the pod manifest path.
*/

use model::modeled_types::Identifier;
use simplelog::{Config as LogConfig, LevelFilter, SimpleLogger};
use snafu::{ensure, OptionExt, ResultExt};
use std::collections::HashMap;
use std::env;
use std::fs;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::process;
use std::str::FromStr;

use model::modeled_types::Identifier;
use tempfile::{NamedTempFile, TempDir};

// FIXME Get from configuration in the future
const DEFAULT_API_SOCKET: &str = "/run/api.sock";

const STATIC_POD_DIR: &str = "/etc/kubernetes/static-pods";
const ETC_KUBE_DIR: &str = "/etc/kubernetes";

type Result<T> = std::result::Result<T, error::Error>;

Expand Down Expand Up @@ -54,13 +56,32 @@ where
S2: AsRef<[u8]>,
{
let name = name.as_ref();

let dir = Path::new(STATIC_POD_DIR);
fs::create_dir_all(&dir).context(error::Mkdir { dir: &dir })?;
let path = dir.join(name);
// Create the file if it does not exist, completely replace its contents
// if it does (constitutes an update).
fs::write(path, manifest).context(error::ManifestWrite { name })?;
let manifest = manifest.as_ref();

let target_dir = Path::new(STATIC_POD_DIR);
fs::create_dir_all(&target_dir).context(error::Mkdir { dir: &target_dir })?;

// Create a temporary directory adjacent to the static pods directory. This directory will be
// automatically cleaned-up as soon as it goes out of scope.
let tmp_dir = TempDir::new_in(ETC_KUBE_DIR).context(error::CreateTempdir)?;

// Create the pod manifest file as a temporary file in an adjacent temp directory first and
// finish writing to it before swapping any files out in the target static pods directory.
let mut temp_manifest_file =
NamedTempFile::new_in(tmp_dir.path()).context(error::CreateTempfile)?;
temp_manifest_file
.write(manifest)
.context(error::ManifestWrite { name })?;

let target_path = target_dir.join(name);
debug!(
"Writing static pod manifest file to '{}'",
target_path.display()
);
// Create the file if it does not exist. If it does exist, atomically replace it.
temp_manifest_file
.persist(&target_path)
.context(error::PersistPodManifest { path: target_path })?;

Ok(())
}
Expand Down Expand Up @@ -277,5 +298,17 @@ mod error {
name: String,
source: std::io::Error,
},

#[snafu(display("Failed to create temporary directory for pod manifests: {}", source))]
CreateTempdir { source: std::io::Error },

#[snafu(display("Failed to create tempfile for writing pod manifest: {}", source))]
CreateTempfile { source: std::io::Error },

#[snafu(display("Failed to create pod manifest file '{}': {}", path.display(), source))]
PersistPodManifest {
path: PathBuf,
source: tempfile::PersistError,
},
}
}

0 comments on commit bf996cb

Please sign in to comment.