Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
amousset committed May 4, 2022
1 parent f16cdbd commit 4deb1dc
Show file tree
Hide file tree
Showing 11 changed files with 252 additions and 77 deletions.
3 changes: 0 additions & 3 deletions relay/sources/Makefile
Expand Up @@ -90,7 +90,6 @@ install: build
mkdir -p $(DESTDIR)/var/rudder/share
mkdir -p $(DESTDIR)/var/log/rudder/apache2/
mkdir -p $(DESTDIR)/etc/sysconfig/
mkdir -p $(DESTDIR)/etc/cron.d/
mkdir -p $(DESTDIR)/etc/sudoers.d/
mkdir -p $(DESTDIR)/usr/lib/systemd/system/

Expand Down Expand Up @@ -126,9 +125,7 @@ install: build
# Others
install -m 644 openssl.cnf $(DESTDIR)/opt/rudder/etc/ssl/openssl.cnf
install -m 644 rudder-relay-apache $(DESTDIR)/etc/sysconfig/rudder-relay-apache
install -m 644 rudder-relay.cron $(DESTDIR)/etc/cron.d/rudder-relay
install -m 644 rudder-relay.sudo $(DESTDIR)/etc/sudoers.d/rudder-relay
install -m 755 relay-cleanup $(DESTDIR)/opt/rudder/bin/relay-cleanup

# Copy stub rudder-networks*.conf
install -m 644 apache/rudder-networks-24.conf $(DESTDIR)/opt/rudder/etc/
Expand Down
14 changes: 0 additions & 14 deletions relay/sources/relay-cleanup

This file was deleted.

48 changes: 41 additions & 7 deletions relay/sources/relayd/src/configuration/main.rs
@@ -1,12 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later WITH GPL-3.0-linking-source-exception
// SPDX-FileCopyrightText: 2019-2020 Normation SAS

use crate::{configuration::Secret, data::node::NodeId};
use anyhow::{anyhow, Error};
use serde::{
de::{Deserializer, Error as SerdeError, Unexpected, Visitor},
Deserialize,
};
use std::{
collections::HashSet,
convert::TryFrom,
Expand All @@ -16,8 +10,16 @@ use std::{
str::FromStr,
time::Duration,
};

use anyhow::{anyhow, Error};
use serde::{
de::{Deserializer, Error as SerdeError, Unexpected, Visitor},
Deserialize,
};
use tracing::{debug, warn};

use crate::{configuration::Secret, data::node::NodeId};

pub type BaseDirectory = PathBuf;
pub type WatchedDirectory = PathBuf;
pub type NodesListFile = PathBuf;
Expand Down Expand Up @@ -472,10 +474,34 @@ impl Default for RemoteRun {
}
}

#[derive(Deserialize, Debug, PartialEq, Eq, Copy, Clone)]
pub struct SharedFilesCleanupConfig {
#[serde(deserialize_with = "compat_humantime")]
#[serde(default = "CleanupConfig::default_cleanup_frequency")]
pub frequency: Duration,
}

impl SharedFilesCleanupConfig {
/// 10 minutes
fn default_cleanup_frequency() -> Duration {
Duration::from_secs(600)
}
}

impl Default for SharedFilesCleanupConfig {
fn default() -> Self {
Self {
frequency: Self::default_cleanup_frequency(),
}
}
}

#[derive(Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct SharedFiles {
#[serde(default = "SharedFiles::default_path")]
pub path: PathBuf,
#[serde(default)]
pub cleanup: SharedFilesCleanupConfig,
}

impl SharedFiles {
Expand All @@ -488,6 +514,7 @@ impl Default for SharedFiles {
fn default() -> Self {
Self {
path: Self::default_path(),
cleanup: SharedFilesCleanupConfig::default(),
}
}
}
Expand Down Expand Up @@ -616,9 +643,10 @@ impl Default for UpstreamConfig {

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

use super::*;

#[test]
fn it_parses_listen_with_hostname() {
let default = "[general]\n\
Expand Down Expand Up @@ -715,6 +743,9 @@ mod tests {
},
shared_files: SharedFiles {
path: PathBuf::from("/var/rudder/shared-files/"),
cleanup: SharedFilesCleanupConfig {
frequency: Duration::from_secs(600),
},
},
shared_folder: SharedFolder {
path: PathBuf::from("/var/rudder/configuration-repository/shared-files/"),
Expand Down Expand Up @@ -813,6 +844,9 @@ mod tests {
},
shared_files: SharedFiles {
path: PathBuf::from("tests/api_shared_files"),
cleanup: SharedFilesCleanupConfig {
frequency: Duration::from_secs(43),
},
},
shared_folder: SharedFolder {
path: PathBuf::from("tests/api_shared_folder"),
Expand Down
59 changes: 32 additions & 27 deletions relay/sources/relayd/src/lib.rs
Expand Up @@ -4,36 +4,11 @@
#[macro_use]
extern crate diesel;

pub mod api;
pub mod configuration;
pub mod data;
pub mod error;
pub mod hashing;
pub mod http_client;
pub mod input;
pub mod metrics;
pub mod output;
pub mod processing;

use crate::{
configuration::{
cli::CliConfiguration,
logging::LogConfig,
main::{
Configuration, InventoryOutputSelect, OutputSelect, PeerAuthentication,
ReportingOutputSelect,
},
},
data::node::{NodeId, NodesList},
http_client::HttpClient,
metrics::{MANAGED_NODES, SUB_NODES},
output::database::{pg_pool, PgPool},
processing::{inventory, reporting},
};
use anyhow::Error;
use std::{
collections::HashMap, fs, fs::create_dir_all, process::exit, string::ToString, sync::Arc,
};

use anyhow::Error;
use tokio::{
signal::unix::{signal, SignalKind},
sync::RwLock,
Expand All @@ -48,6 +23,33 @@ use tracing_subscriber::{
reload::Handle,
};

use crate::{
configuration::{
cli::CliConfiguration,
logging::LogConfig,
main::{
Configuration, InventoryOutputSelect, OutputSelect, PeerAuthentication,
ReportingOutputSelect,
},
},
data::node::{NodeId, NodesList},
http_client::HttpClient,
metrics::{MANAGED_NODES, SUB_NODES},
output::database::{pg_pool, PgPool},
processing::{inventory, reporting, shared_files},
};

pub mod api;
pub mod configuration;
pub mod data;
pub mod error;
pub mod hashing;
pub mod http_client;
pub mod input;
pub mod metrics;
pub mod output;
pub mod processing;

pub const CRATE_NAME: &str = env!("CARGO_PKG_NAME");
pub const CRATE_VERSION: &str = env!("CARGO_PKG_VERSION");

Expand Down Expand Up @@ -153,6 +155,9 @@ pub fn start(cli_cfg: CliConfiguration, reload_handle: LogHandle) -> Result<(),
info!("Skipping inventory as it is disabled");
}

// Spawn shared-files cleaner
shared_files::start(&job_config);

// Initialize metrics
job_config.reload_metrics().await;

Expand Down
4 changes: 3 additions & 1 deletion relay/sources/relayd/src/processing.rs
@@ -1,13 +1,15 @@
// SPDX-License-Identifier: GPL-3.0-or-later WITH GPL-3.0-linking-source-exception
// SPDX-FileCopyrightText: 2019-2020 Normation SAS

use anyhow::Error;
use std::path::PathBuf;

use anyhow::Error;
use tokio::fs::{remove_file, rename};
use tracing::debug;

pub mod inventory;
pub mod reporting;
pub mod shared_files;

pub type ReceivedFile = PathBuf;
pub type RootDirectory = PathBuf;
Expand Down
140 changes: 140 additions & 0 deletions relay/sources/relayd/src/processing/shared_files.rs
@@ -0,0 +1,140 @@
// SPDX-License-Identifier: GPL-3.0-or-later WITH GPL-3.0-linking-source-exception
// SPDX-FileCopyrightText: 2019-2020 Normation SAS

use std::{
path::Path,
str::{self, FromStr},
sync::Arc,
time::{SystemTime, UNIX_EPOCH},
};

use anyhow::{anyhow, Error};
use tokio::{
fs::{read, read_dir, remove_file},
time::interval,
};
use tracing::{debug, error, span, Level};

use crate::{
configuration::main::{SharedFilesCleanupConfig, WatchedDirectory},
data::shared_file::Metadata,
JobConfig,
};

pub fn start(job_config: &Arc<JobConfig>) {
let span = span!(Level::TRACE, "shared_files");
let _enter = span.enter();

let root_path = job_config.cfg.shared_files.path.clone();

tokio::spawn(cleanup(root_path, job_config.cfg.shared_files.cleanup));
}

async fn expired(file: &Path) -> Result<bool, Error> {
let raw = read(file.with_extension("metadata")).await?;
let metadata = str::from_utf8(&raw)?;

let parsed = Metadata::from_str(metadata)?;
let expiration = parsed
.expires
.ok_or(anyhow!("Missing expires field in {:?}", file))?;

let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_secs();

Ok(expiration < now as i64)
}

// special cleanup implementation as retention is based on shared files metadata content
pub async fn cleanup(path: WatchedDirectory, cfg: SharedFilesCleanupConfig) -> Result<(), Error> {
let mut timer = interval(cfg.frequency);

loop {
timer.tick().await;
debug!("cleaning shared-files in {:?}", path);

// First level: source node directory
let mut dirs = match read_dir(path.clone()).await {
Ok(f) => f,
Err(e) => {
error!("list file: {}", e);
continue;
}
};
loop {
let entry = match dirs.next_entry().await {
Ok(Some(e)) if e.file_type().await?.is_dir() => e,
// Nothing to do
Ok(_) => break,
Err(e) => {
error!("entry error: {}", e);
continue;
}
};

// Second level: destination directory
let mut dirs = match read_dir(entry.path().join("files")).await {
Ok(f) => f,
Err(e) => {
error!("list file: {}", e);
continue;
}
};
loop {
let entry = match dirs.next_entry().await {
Ok(Some(e)) if e.file_type().await?.is_dir() => e,
// Nothing to do
Ok(_) => break,
Err(e) => {
error!("entry error: {}", e);
continue;
}
};

// Third level: shared file
let mut files = match read_dir(entry.path()).await {
Ok(f) => f,
Err(e) => {
error!("list file: {}", e);
continue;
}
};
loop {
let entry = match files.next_entry().await {
Ok(Some(e)) if Path::exists(&e.path().with_extension("metadata")) => e,
// Nothing to do
Ok(_) => break,
Err(e) => {
error!("entry error: {}", e);
continue;
}
};

let shared_file = entry.path();
match expired(&shared_file).await {
Ok(true) => {
debug!("removing expired shared-file: {:?}", shared_file);
remove_file(shared_file)
.await
.unwrap_or_else(|e| error!("removal error: {}", e));
}
_ => break,
}
}
}
}
}
}

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

#[tokio::test]
async fn it_reads_expire_metadata() {
assert!(expired(Path::new("tests/api_shared_files/37817c4d-fbf7-4850-a985-50021f4e8f41/files/e745a140-40bc-4b86-b6dc-084488fc906b/file.metadata")).await.unwrap());
assert!(!expired(Path::new("tests/api_shared_files/37817c4d-fbf7-4850-a985-50021f4e8f41/files/e745a140-40bc-4b86-b6dc-084488fc906b/file-future.metadata")).await.unwrap());
}
}
@@ -0,0 +1,9 @@
header=rudder-signature-v1
algorithm=sha512
digest=9ae39f50bbbd3a2e529a1be61e739b814b9470a0704ef8dd7d3b78d44c2813ad062004f42dab3214a4779f8b4e8a5935cc92ff0313845377c58db605a0aaa5cffbe05e5809d4d646249cbe1fdbc6c498a7bc533415cb32de1b1f782c2f6b453b737999c4f8a15875cfe6a2808668e8c17986e100395633f702e709c2d49b7aa6eca6503e98360d58ca08ba0e91455512966a72036eeaa8c53dd016a129b2c366578c43d16c59208bdc34b39c81a8c88c073fc44bf64375644f6260d27de400ce790bd0b43251ec4640e2b9c0e2916b5e2d08395eec19f3f24a5c6bd39e2a6685f540e43c43508a98bca5cb7825022db8169080d9d3f8660ffc9b11aaa9b8088311f9bc3a0f1d822055d7ec1fedb9adabeeac7625106fa0597dfebd0d22e4703feedc2137ff705193249707e228a139015f49455fa1742e83676b5af5f84e58b71bad7846fcd731326982a4f48fd301360cc6e911554cdf193b99c7491c707b2ea373bc7ebf71d02bcdd34f4812b701977e79e7ed1b9ab6522f5e8e048cf024f24e7f0a2fcc47d6f72543acf421560da8aa9bc71c88083173122fb4905e683f4be91155d8c87f948b8b0357b10594dd61cf33dff8f3bb418a1fdc5f88ea0589906adbff1774d310829576326e4d376a8d6bc495240d030e79c76bde2daa95c051aae8b8fb2dca9327b120d494d6e9fe4dcd30cda6ba6a110cc3055a6f2a4b146d
hash_value=dda78e9b97a69aca3cff21de266246bde0d91bc4b61df72bfb0387564ac0c7bd64dd4caca39ce1ef400f32aa711ec4909789705beec93314eb65fabd5183bbfe
short_pubkey=MIICCgKCAgEAuok8JTvRssiupO0IfH4OGnWFqQg5dmI/4JsCiPEUf78iFBwFFpwuNXDJXCKaHtpjuc3DAy9l7fmZ+bQmkfde+Qo3yAd2ZsId80TBZOy6uFQyl4ASLNgY8RKIFxD6+AsutI27KexSnL3QLCgywnheRv4Ur31a6MVY1xfSQnADruBBad+5SaF3hTpEcAMg2hDQsIcyR32MPRy9MOVmvBlgI2hZsgh9QQf9wTLxGuMw/pJKOPRwwFkk/5bhFBve2sL1OI0pRsM6i7SxNXRhM6NWlmObhP+Z7C6N7TY00Z+tizgETmYJ35llyInjc1i+0bWaj5p3cbSCVdQ5zomZ3L9XbsWmjl0P/cw06qqNPuLR799K+R1XgA94nUUzo2pVigPh6sj2XMS8FOWXMXy2TNEOA+NQV5+vYwIlUizvB/HHSc3WKqNGgCifdJBmJJ8QTg5cJE6s+91O99eMMAQ0Ecj+nY5QEYkbIn4gjNpojam3jyS72o0J4nlj4ECbR/rj6L5b+kj5F3DbYqSdLC+crKUIoBZH1msCuJcQ9Zk/YHw87iVyWoZOVtJUUaw3n8vH/YCWPBQRzZp+4zlyIYJIIz+V/FJZX5YNW9XgoeRG8Q0mOmLy0FbQUS/klYlpeW3PKLSQmcSLvrgZnhKMyhEohC0zOSqJU0ui4VUWY5tv1bhbTo8CAwEAAQ==
hostname=node1.rudder.local
keydate=2020-01-24 12:17:59.014153459 +0100
keyid=B85B4E8F
expires=2061475500
3 changes: 3 additions & 0 deletions relay/sources/relayd/tests/files/config/main.conf
Expand Up @@ -59,6 +59,9 @@ use_sudo = false
[shared_files]
path = "tests/api_shared_files"

[shared_files.cleanup]
frequency = "43s"

[shared_folder]
path = "tests/api_shared_folder"

0 comments on commit 4deb1dc

Please sign in to comment.