Skip to content

Commit 8174eca

Browse files
committed
Improve documentation
Signed-off-by: Marc Schöchlin <[email protected]>
1 parent 7c2cb23 commit 8174eca

File tree

2 files changed

+80
-55
lines changed

2 files changed

+80
-55
lines changed

README.md

Lines changed: 66 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,72 @@ Convenient management and execution of command on groups of hosts : *A ssh loop
55
I created this tool more than one decade ago, because existing tools suck.
66
(Cluster Shell, Bolt, ... and probably because of NIH)
77

8-
# Install
9-
10-
Software prerequisites:
11-
* rustc
12-
* ssh
13-
* screen
14-
15-
Install script:
16-
17-
On Ubuntu just do:
18-
```
19-
INSTALLDIR="/opt/"
20-
sudo apt-get install rustc ssh screen
21-
cd ${INSTALLDIR?Installation Dir}
22-
git clone https://github.com/scoopex/hostctl.git hostctl
23-
cd hostctl
24-
cargo build --release
25-
ln -snf $INSTALLDIR/hostctl/target/release/hostctl /usr/local/bin/hostctl
26-
target/release/hostctl generate-completions bash > misc/hostctl_bash_completion.sh
27-
target/release/hostctl generate-completions zsh > misc/hostctl_zsh_completion.sh
28-
target/release/hostctl generate-completions fish > misc/hostctl_fish_completion.sh
29-
echo "source $INSTALLDIR/hostctl/misc/hostctl_bash_completion.sh" >> .bashrc
30-
exec bash
31-
```
32-
33-
Configure your environments:
34-
35-
* Use the "ssh-agent"
36-
* Activate ssh agent forwarding (openssh: `ForwardAgent yes`) on your desktop
37-
ssh client and all systems you want to use "hostctl"
38-
* Activate ssh agent-forwarding (openssh: `AllowAgentForwarding yes`, this should be the default value)
39-
on your ssh servers
40-
41-
# Usage
8+
# Install and use
9+
10+
1. Download ar current release from the [releases page](https://github.com/scoopex/hostctl/releases)
11+
2. Extract the archive
12+
```bash
13+
cd ${INSTALL_DIR?The installation base directory}
14+
tar xvf hostctl-v0.9.11.tar.gz
15+
```
16+
3. Add the tool to a directory which is in your PATH search-scope
17+
```bash
18+
cd ${INSTALL_DIR?The installation base directory}/hostctl
19+
ln -snf $PWD/hostctl ~/bin/hostctl
20+
```
21+
4. Create directories
22+
```
23+
mkdir -p ~/.hostctl/repices
24+
```
25+
5. Configure your environments:
26+
(See also "EXAMPLES" section)
27+
```
28+
echo << 'EOF'
29+
#<groupname> : <host>, <host>, ...
30+
web2 : barfoo-l01-ap01, barfoo-l01-ap02, barfoo-l01-ap03, barfoo-l01-ap04, barfoo-l01-ap05, barfoo-l01-ap06
31+
db2 : barfoo-l01-db01, barfoo-l01-db02, barfoo-l01-db03
32+
EOF
33+
```
34+
6. Add shell completion to your shell init
35+
(`~/.bashrc`, `~/.zshrc`)
36+
```
37+
source ${INSTALL_DIR?The installation base directory}/hostctl_$( basename $SHELL)_completion.sh
38+
```
39+
6. Configure SSH
40+
* Use the "ssh-agent"
41+
* Activate ssh agent forwarding (openssh: `ForwardAgent yes`) on your desktop
42+
ssh client and all systems you want to use "hostctl"
43+
* Activate ssh agent-forwarding (openssh: `AllowAgentForwarding yes`, this should be the default value)
44+
on your ssh servers
4245
4346
Invoke hostctl to execute commands or scripts on the specified hosts.
4447
45-
See also "EXAMPLES" section.
48+
# Develop
49+
50+
1. Install software prerequisites:
51+
```
52+
sudo apt-get install rustc ssh screen
53+
```
54+
2. Build it and add it to a directory which is in your PATH search-scope
55+
```
56+
cd ${INSTALL_DIR?The installation base directory}/hostctl
57+
git clone https://github.com/scoopex/hostctl.git hostctl
58+
cd hostctl
59+
cargo build --release
60+
ln -snf ${INSTALL_DIR?The installation base directory}/hostctl/target/release/hostctl ~/bin/hostctl
61+
```
62+
3. Build completions
63+
```
64+
target/release/hostctl generate-completions bash > misc/hostctl_bash_completion.sh
65+
target/release/hostctl generate-completions zsh > misc/hostctl_zsh_completion.sh
66+
target/release/hostctl generate-completions fish > misc/hostctl_fish_completion.sh
67+
echo "source $INSTALLDIR/hostctl/misc/hostctl_bash_completion.sh" >> .bashrc
68+
exec bash
69+
```
70+
4. Execute step 4 and later in the previous section
71+
72+
# Help Output
4673
47-
# Help
4874
(output of "hostctl --help")
4975
```
5076
$ hostctl --help
@@ -122,29 +148,23 @@ Options:
122148
123149
# Configuration file format (hostctl.conf):
124150
```
125-
#<perl-regex for visibility> : <groupname> : <host>, <host>, ...
126-
foobar-l01-(ap|db)\d+ : web1 : foobar-l01-ap01, foobar-l01-ap02, foobar-l01-ap03, foobar-l01-ap04, foobar-l01-ap05, foobar-l01-ap06
127-
foobar-l01-(ap|db)\d+ : db1 : foobar-l01-db01, foobar-l01-db02, foobar-l01-db03
128-
129-
jump-barfoo : web2 : barfoo-l01-ap01, barfoo-l01-ap02, barfoo-l01-ap03, barfoo-l01-ap04, barfoo-l01-ap05, barfoo-l01-ap06
130-
jump-barfoo : db2 : barfoo-l01-db01, barfoo-l01-db02, barfoo-l01-db03
151+
#<groupname> : <host>, <host>, ...
152+
web2 : barfoo-l01-ap01, barfoo-l01-ap02, barfoo-l01-ap03, barfoo-l01-ap04, barfoo-l01-ap05, barfoo-l01-ap06
153+
db2 : barfoo-l01-db01, barfoo-l01-db02, barfoo-l01-db03
131154
```
132155
133-
* Hostgroup web1 is only visible/usable on hosts which match to regex "foobar-l01-(ap|db)\d+" - i.e. foobar-l01-ap99
134-
* Hostgroup db1 is only visible/usable on hosts which match to regex "foobar-l01-(ap|db)\d+" - i.e. foobar-l01-ap99
135156
* Hostgroup web2 is only visible/usable on host jump-barfoo
136157
* Hostgroup db2 is only visible/usable on host jump-barfoo
137158
138159
139160
# Missing features
140161
162+
- Implement completion of hosts and groups
141163
- cluster shell mode with "--inscreen" : send STDIN of a master terminal to all screens
142164
- packaging for rpm and deb
143-
- Show the next node on prompting
144165
- Manual sorting of nodes
145166
- Health check cmd for finishing the node
146167
147-
148168
# Licence and Authors
149169
150170
Additional authors are very welcome - just submit your patches as pull requests.

src/groups_config.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
use crate::utils;
2+
use regex::Regex;
13
use std::collections::{HashMap, HashSet};
24
use std::env;
3-
use regex::Regex;
4-
use crate::utils;
55

66
pub fn dump_batch_list(items: Vec<String>) {
77
let sorted_vec = unified_node_list(items);
@@ -35,12 +35,13 @@ pub fn dump_groups(items: Vec<String>, json: bool) {
3535
}
3636

3737
fn get_groups_and_nodes(items: Vec<String>) -> HashMap<String, Vec<String>> {
38-
3938
let mut groups_map = std::collections::HashMap::new();
4039
let cfg_files = [
41-
format!("{}/hostctl.conf",
42-
env::var("HOSTCTL_CONFIG")
43-
.unwrap_or_else(|_| "/not/existing/default/path/to/config".to_string())),
40+
format!(
41+
"{}/hostctl.conf",
42+
env::var("HOSTCTL_CONFIG")
43+
.unwrap_or_else(|_| "/not/existing/default/path/to/config".to_string())
44+
),
4445
format!("{}/.hostctl/hostctl.conf", env!("HOME")),
4546
format!("{}/hostctl.conf", env!("PWD")),
4647
];
@@ -52,18 +53,22 @@ fn get_groups_and_nodes(items: Vec<String>) -> HashMap<String, Vec<String>> {
5253

5354
let re = Regex::new(r"^([a-z0-9-]+)\s*:\s*([a-z0-9-,\s]+)(#.*)?").unwrap();
5455

55-
5656
for cfg_file in &cfg_files {
5757
if let Ok(lines) = utils::read_lines(cfg_file) {
5858
for line in lines {
5959
if let Ok(host_line) = line {
6060
if let Some(captures) = re.captures(&*host_line) {
6161
let group_name = captures.get(1).map_or("", |m| m.as_str());
6262
let members_str = captures.get(2).map_or("", |m| m.as_str());
63-
let nodes = members_str.split(',').map(|s| s.trim().to_string()).collect::<Vec<_>>();
63+
let nodes = members_str
64+
.split(',')
65+
.map(|s| s.trim().to_string())
66+
.collect::<Vec<_>>();
6467

6568
if select_all || items.contains(&group_name.to_string()) {
66-
let group = groups_map.entry(group_name.to_string()).or_insert(Vec::new());
69+
let group = groups_map
70+
.entry(group_name.to_string())
71+
.or_insert(Vec::new());
6772
group.extend(nodes);
6873
}
6974
}

0 commit comments

Comments
 (0)