-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add ansible run to the
deploy
command
Right now this only provisions the genesis node. We need to implement the retrieval of the genesis IP and peer ID before we can run against the remaining nodes. It uses a very similar pattern to Terraform, with an interface, so that we can do behaviour-based unit testing.
- Loading branch information
Showing
7 changed files
with
396 additions
and
71 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#!/bin/bash | ||
|
||
NODE_DATA_DIR_PATH=~/.local/share/safe/node | ||
LOGFILE=$NODE_DATA_DIR_PATH/resource-usage.log | ||
|
||
exec > >(tee -a $LOGFILE) 2>&1 | ||
|
||
while true; do | ||
echo "------------------------------------------------------" | ||
echo "Report for $(date)" | ||
echo "------------------------------------------------------" | ||
echo "Checking $(hostname) on $(hostname -I | awk '{print $1}')" | ||
printf "%-52s %-8s %-10s %-10s %s\n" \ | ||
"Node " \ | ||
"PID" \ | ||
"Memory (MB)" \ | ||
"CPU (%)" \ | ||
"Record Count" | ||
running_process_count=0 | ||
for folder in $NODE_DATA_DIR_PATH/*; do | ||
if [ ! -d "$folder" ]; then continue; fi | ||
peer_id=$(basename "$folder") | ||
pid=$(cat "$folder/safenode.pid") | ||
if [ -z "$pid" ]; then | ||
echo "No PID found for $peer_id" | ||
continue | ||
fi | ||
if [ ! -d "/proc/$pid" ]; then | ||
echo "PID $pid for $peer_id is not currently running" | ||
continue | ||
fi | ||
rss=$(ps -p $pid -o rss=) | ||
cpu=$(top -b -n1 -p $pid | awk 'NR>7 {print $9}') | ||
count=$(find "$folder" -name '*' -not -name '*.pid' -type f | wc -l) | ||
printf "%-52s %-8s %-10s %-10s %s\n" \ | ||
"$peer_id" \ | ||
"$pid" \ | ||
"$(awk "BEGIN {print $rss/1024}")" \ | ||
"$cpu" \ | ||
"$count" | ||
running_process_count=$((running_process_count + 1)) | ||
done | ||
echo "Total node processes: $running_process_count" | ||
sleep 10 | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
// Copyright (c) 2023, MaidSafe. | ||
// All rights reserved. | ||
// | ||
// This SAFE Network Software is licensed under the BSD-3-Clause license. | ||
// Please see the LICENSE file for more details. | ||
use crate::error::Result; | ||
use crate::run_external_command; | ||
use crate::CloudProvider; | ||
#[cfg(test)] | ||
use mockall::automock; | ||
use std::path::PathBuf; | ||
|
||
/// Ansible has multiple 'binaries', e.g., `ansible-playbook`, `ansible-inventory` etc. that are | ||
/// wrappers around the main `ansible` program. It would be a bit cumbersome to create a different | ||
/// runner for all of them, so we can just use this enum to control which program to run. | ||
/// | ||
/// Ansible is a Python program, so strictly speaking these are not binaries, but we still use them | ||
/// like a program. | ||
pub enum AnsibleBinary { | ||
AnsiblePlaybook, | ||
AnsibleInventory, | ||
Ansible, | ||
} | ||
|
||
impl std::fmt::Display for AnsibleBinary { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
match self { | ||
AnsibleBinary::AnsiblePlaybook => write!(f, "ansible-playbook"), | ||
AnsibleBinary::AnsibleInventory => write!(f, "ansible-inventory"), | ||
AnsibleBinary::Ansible => write!(f, "ansible"), | ||
} | ||
} | ||
} | ||
|
||
/// Provides an interface for running Ansible. | ||
/// | ||
/// This trait exists for unit testing: it enables testing behaviour without actually calling the | ||
/// Ansible process. | ||
#[cfg_attr(test, automock)] | ||
pub trait AnsibleRunnerInterface { | ||
fn run_playbook( | ||
&self, | ||
playbook_path: PathBuf, | ||
inventory_path: PathBuf, | ||
user: String, | ||
extra_vars_document: Option<String>, | ||
) -> Result<()>; | ||
} | ||
|
||
pub struct AnsibleRunner { | ||
pub provider: CloudProvider, | ||
pub working_directory_path: PathBuf, | ||
pub ssh_sk_path: PathBuf, | ||
pub vault_password_file_path: PathBuf, | ||
} | ||
|
||
impl AnsibleRunner { | ||
pub fn new( | ||
working_directory_path: PathBuf, | ||
provider: CloudProvider, | ||
ssh_sk_path: PathBuf, | ||
vault_password_file_path: PathBuf, | ||
) -> AnsibleRunner { | ||
AnsibleRunner { | ||
provider, | ||
working_directory_path, | ||
ssh_sk_path, | ||
vault_password_file_path, | ||
} | ||
} | ||
} | ||
|
||
impl AnsibleRunnerInterface for AnsibleRunner { | ||
fn run_playbook( | ||
&self, | ||
playbook_path: PathBuf, | ||
inventory_path: PathBuf, | ||
user: String, | ||
extra_vars_document: Option<String>, | ||
) -> Result<()> { | ||
// Using `to_string_lossy` will suffice here. With `to_str` returning an `Option`, to avoid | ||
// unwrapping you would need to `ok_or_else` on every path, and maybe even introduce a new | ||
// error variant, which is very cumbersome. These paths are extremely unlikely to have any | ||
// unicode characters in them. | ||
let mut args = vec![ | ||
"--inventory".to_string(), | ||
inventory_path.to_string_lossy().to_string(), | ||
"--private-key".to_string(), | ||
self.ssh_sk_path.to_string_lossy().to_string(), | ||
"--user".to_string(), | ||
user, | ||
"--vault-password-file".to_string(), | ||
self.vault_password_file_path.to_string_lossy().to_string(), | ||
]; | ||
if let Some(extra_vars) = extra_vars_document { | ||
args.push("--extra-vars".to_string()); | ||
args.push(extra_vars); | ||
} | ||
args.push(playbook_path.to_string_lossy().to_string()); | ||
run_external_command( | ||
PathBuf::from(AnsibleBinary::AnsiblePlaybook.to_string()), | ||
self.working_directory_path.clone(), | ||
args, | ||
false, | ||
)?; | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.