Skip to content

Commit

Permalink
Resolve volume mount paths
Browse files Browse the repository at this point in the history
This commit adds function for deciding what host paths should be used to back
configured volumes. No volumes are mounted, but a debug log is emitted to
allow inspection of the generated mounts.

Signed-off-by: Richard Lupton <[email protected]>
  • Loading branch information
rlupton20 committed Oct 17, 2019
1 parent 7527065 commit 4fed2c3
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 2 deletions.
47 changes: 47 additions & 0 deletions 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 Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ serde_yaml = "0.7"
structopt = "0.2"
uuid = { version = "0.6", features = ["v4"] }
yaml-rust = "0.4.3"
rust-crypto = "^0.2"

[dev-dependencies]
tempdir = "0.3.7"
4 changes: 2 additions & 2 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ impl Shell {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub(crate) struct Volume {
#[serde(default = "default_to_false")]
shared: bool,
mount: path::PathBuf,
pub(crate) shared: bool,
pub(crate) mount: path::PathBuf,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
Expand Down
10 changes: 10 additions & 0 deletions src/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ pub struct Environment {
pub floki_root: path::PathBuf,
pub config_file: path::PathBuf,
pub ssh_agent_socket: Option<String>,
pub floki_workspace: path::PathBuf,
}

impl Environment {
Expand All @@ -24,6 +25,7 @@ impl Environment {
floki_root: floki_root,
config_file: config_path,
ssh_agent_socket: get_ssh_agent_socket_path(),
floki_workspace: get_floki_work_path()?,
})
}
}
Expand Down Expand Up @@ -89,6 +91,14 @@ fn resolve_floki_root_and_config(
}
}

/// Resolve a directory for floki to use for user-global file (caches etc)
fn get_floki_work_path() -> Result<path::PathBuf, Error> {
let root: path::PathBuf = env::var("HOME")
.unwrap_or(format!("/tmp/{}/", get_user_details()?.0))
.into();
Ok(root.join(".floki"))
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
8 changes: 8 additions & 0 deletions src/interpret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::config::FlokiConfig;
use crate::dind::Dind;
use crate::environment::Environment;
use crate::errors;
use crate::volumes::resolve_volume_mounts;

use failure::Error;
use std::path;
Expand All @@ -14,6 +15,13 @@ pub(crate) fn run_container(
config: &FlokiConfig,
command: &str,
) -> Result<(), Error> {
let volumes = resolve_volume_mounts(
&environ.floki_root,
&environ.floki_workspace,
&config.volumes,
);
debug!("Resolved volume mounts: {:?}", volumes);

let (mut cmd, mut dind) = build_basic_command(&environ.floki_root, &config)?;

cmd = configure_dind(cmd, &config, &mut dind)?;
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mod errors;
mod image;
mod interpret;
mod verify;
mod volumes;

use cli::{Cli, Subcommand};
use config::FlokiConfig;
Expand Down
124 changes: 124 additions & 0 deletions src/volumes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
use std::collections::BTreeMap;
use std::path;

use crypto::digest::Digest;
use crypto::sha2::Sha256;

use crate::config::Volume;

pub(crate) fn resolve_volume_mounts(
floki_root: &path::PathBuf,
work_path: &path::PathBuf,
volumes: &BTreeMap<String, Volume>,
) -> Vec<(path::PathBuf, path::PathBuf)> {
volumes
.iter()
.map(|(name, volume)| {
(
cache_path(work_path, floki_root, name, volume),
volume.mount.clone(),
)
})
.collect()
}

fn cache_path(
work_path: &path::PathBuf,
floki_root: &path::PathBuf,
name: &str,
config: &Volume,
) -> path::PathBuf {
let folder = prefix_cache(config.shared, floki_root) + name;
work_path.join(".cache/").join::<String>(folder)
}

fn prefix_cache(shared: bool, floki_root: &path::PathBuf) -> String {
if shared {
"".into()
} else {
hash_path(floki_root) + "-"
}
}

fn hash_path(path: &path::PathBuf) -> String {
let mut hasher = Sha256::new();
hasher.input_str(&path.as_os_str().to_string_lossy());
hasher.result_str()
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_shared_cache_path_is_shared_across_flokis() {
let cache_1 = cache_path(
&"work_path".into(),
&"/floki/root/1/".into(),
"cache",
&Volume {
shared: true,
mount: "/".into(),
},
);
let cache_2 = cache_path(
&"work_path".into(),
&"/floki/root/2/".into(),
"cache",
&Volume {
shared: true,
mount: "/".into(),
},
);

assert_eq!(cache_1, cache_2);
}

#[test]
fn test_local_cache_path_is_not_shared_across_flokis() {
let cache_1 = cache_path(
&"work_path".into(),
&"/floki/root/1/".into(),
"cache",
&Volume {
shared: false,
mount: "/".into(),
},
);
let cache_2 = cache_path(
&"work_path".into(),
&"/floki/root/2/".into(),
"cache",
&Volume {
shared: false,
mount: "/".into(),
},
);

assert_ne!(cache_1, cache_2);
}

#[test]
fn test_local_and_shared_caches_dont_collide() {
let cache_shared = cache_path(
&"work_path".into(),
&"/floki/root/1/".into(),
"cache",
&Volume {
shared: true,
mount: "/".into(),
},
);
let cache_local = cache_path(
&"work_path".into(),
&"/floki/root/1/".into(),
"cache",
&Volume {
shared: false,
mount: "/".into(),
},
);

assert_ne!(cache_shared, cache_local);
}
}

0 comments on commit 4fed2c3

Please sign in to comment.