first of all, MUSSH,MUSSH is a shell development of a small tool, just learn to transport peacekeeping Shell friends can take exercise, do a tool two times development.
[Root@devops-ruifengyun ~]$ apt-get Install Mussh
Reading Package List ... Complete
Analyzing Dependency tree for Package
Reading status information ... Complete
The following packages are installed automatically and do not need them now:
KDE-L10N-ENGB KDE-L10N-ZHCN libffi6:i386 libglib2.0-0:i386
libsystemd-daemon0:i386 libudev1:i386 Python-async python-git python-gitdb
Python-smmap
Use the ' Apt-get autoremove ' to remove them.
The following "new" packages will be installed:
Mussh
0 packages were upgraded, 1 new packages were installed, 0 packages were uninstalled, and 205 packages were not upgraded.
You need to download the 14.4 KB package.
Decompression will consume extra space in 71.7 KB.
Get: 1 http://mirrors.oschina.net/ubuntu/saucy/universe mussh all 1.0-1 [14.4 KB]
Download 14.4 KB, time consuming 0 seconds (30.3 kb/s)
Selecting previously unselected package mussh.
(Reading database ...) The system currently has a total of 234,998 files and directories installed. )
Decompressing mussh (from .../archives/mussh_1.0-1_all.deb) ...
Processing triggers for man-db ...
Setting Mussh (1.0-1) ...
[Root@devops-ruifengyun ~]$
Mussh's help would be quite simple to see his help.
The code is as follows |
Copy Code |
[Root@devops-ruifengyun ~]$ mussh--help
Usage:mussh [OPTIONS] <-h host. | -H hostfile> [-c cmd] [-C ScriptFile]
Mussh--help for full help text
Send a command or list of commands to multiple hosts.
OPTIONS:
--help this text.
-d [n] Verbose Debug. Prints each action, all hosts
and commands to is executed to STDERR. ' N ' Can
Be from 0 to 2.
-v [n] Ssh debug levels. Can is from 0 to 3.
-M [n] Run concurrently on ' n ' hosts in a time (asynchronous).
Use ' 0 ' (zero) for infinite. (Default if-m)
-Q No output unless necessary.
-I <identity> [identity ...]
Load an identity file. May is used
More than once.
-O <ssh-args> args to passthrough to SSH with-o option.
-A Force loading ssh-agent.
-A does not load ssh-agent.
-B Print Each hosts ' output in a block without mingling
With the other hosts ' output.
-B Allow hosts ' output to mingle. (default)
-U Unique. Eliminate duplicate hosts. (default)
The-u do don't make host list unique.
-P don't fall back to passwords in any host. This would
Skip hosts where keys fail.
-L <login> use ' login ' when no. specified with hostname.
-L <login> Force use the ' login ' name on the all hosts.
-S <shell> Path to shell on remote host. (Default:bash)
-T <secs> Timeout setting for each session.
(Requires OpenSSH 3.8 or newer)
-V Print version info and exit.
PROXY ARGS:
-P [user@]<host>
Host to use as proxy. (Must have MUSSH installed)
-po <ssh-args> args to the SSH on proxy with-o option.
HOST ARGS:
-H [user@]<host> [[user@]<host> ...]
ADD a host to list of hosts. May is
Used more than once.
-h <file> [file ...]
Add contents of file (s) to list of hosts.
Files should have one host per line. Use
"#" for comments.
COMMAND ARGS:
If Neither is specified, commands'll be read from standard input.
-C <command> Add a command or quoted list of commands and
Args to list of commands to is executed on
Each host. May is used more than once.
-c <file> [file ...]
ADD file contents to list of commands to IS
executed on each host. May is used more
than once.
At least one host is required. Arguments are in no particular order.
Examples:
Mussh-h./linuxhosts-c spfiles/testscript.sh
Mussh-c "Cat/etc/hosts"-H myhost.mydomain.com
Comments and Bugs Reports:doughnut@doughnut.net |
Let's go straight to an example where we need to put the End-to-end host in a file. Mussh then invokes the list of H-aware hosts.
[Root@devops-ruifengyun ~]$
http://rfyiamcool.blog.51cto.com/
[Root@devops-ruifengyun ~]$ Cat Mu.list
10.1.25.46
10.1.25.47
10.1.25.48
10.1.25.49
[Root@devops-ruifengyun ~]$
[Root@devops-ruifengyun ~]$
[Root@devops-ruifengyun ~]$ mussh-h./mu.list-c ' dir '
10.154.252.46:a.py Install.log keepalived-1.2.12
10.154.252.46:epel-release-6-8.noarch.rpm Install.log.syslog keepalived-1.2.12.tar.gz
10.154.252.47:install.log Install.log.syslog keepalived-1.2.12 keepalived-1.2.12.tar.gz
10.154.252.48:install.log Install.log.syslog rs.sh
10.154.252.49:install.log Install.log.syslog rs.sh
[Root@devops-ruifengyun ~]$
[Root@devops-ruifengyun ~]$
Test that he has no concurrent features.
[Root@devops-ruifengyun ~]$ time mussh-h,/mu.list-c ' sleep 3;dir '
10.154.252.46:a.py Install.log keepalived-1.2.12
10.154.252.46:epel-release-6-8.noarch.rpm Install.log.syslog keepalived-1.2.12.tar.gz
10.154.252.47:install.log Install.log.syslog keepalived-1.2.12 keepalived-1.2.12.tar.gz
10.154.252.48:install.log Install.log.syslog rs.sh
10.154.252.49:install.log Install.log.syslog rs.sh
Mussh-h./mu.list-c ' sleep 3;dir ' 0.04s user 0.16s system 1% CPU 13.206 Total
[Root@devops-ruifengyun ~]$
Sure enough, no concurrent execution ... This is not too low.
MUSSH support for sending scripts and executing, the CLI command line in MUSSH directly-C followed the script.
[Root@devops-ruifengyun ~]$ time mussh-h./mu.list-c c.sh
10.154.252.46:a.py Install.log keepalived-1.2.12
10.154.252.46:epel-release-6-8.noarch.rpm Install.log.syslog keepalived-1.2.12.tar.gz
10.154.252.47:install.log Install.log.syslog keepalived-1.2.12 keepalived-1.2.12.tar.gz
10.154.252.48:install.log Install.log.syslog rs.sh
10.154.252.49:install.log Install.log.syslog rs.sh
Mussh-h./mu.list-c c.sh 0.10s User 0.17s system 42% CPU 0.629 Total
[Root@devops-ruifengyun ~]$
[Root@devops-ruifengyun ~]$
[Root@devops-ruifengyun ~]$
Let's test the PSSH, which is more high-end than MUSSH, PSSH is a tool developed by Python to bulk manage Linux hosts.
PSSH Related Parameters
Pssh run commands in parallel on multiple hosts
-H Execute Command remote host list, file content format [user@]host[:p ORT]
such as test@172.16.10.10:229
-H Execute Command host, host format User@ip:port
The user name of the-L remote machine
-P maximum allowable number of connections at a time
-P output execution information at execution time
-O output redirected to a file
-E Execution error Redirect to a file
-T sets the command execution timeout
-a prompts for a password and passes the password to SSH (use this parameter if the private key also has a password)
-o set some SSH options
-X sets SSH extra parameters, can be multiple, separated by spaces between different parameters
-X with-X, but only one parameter can be set
-I display standard output and standard error after each host executes
Additional Tools
PSCP transfer files to multiple hosts, similar to SCP
Pscp-h hosts.txt-l IRB2 Foo.txt/home/irb2/foo.txt
Pslurp copy files from multiple remote machines to local
Pnuke parallel in remote host kill process
Pnuke-h Hosts.txt-l irb2 Java
Prsync uses the Rsync protocol to sync from a local computer to a remote host
Prsync-r-H hosts.txt-l irb2 Foo/home/irb2/foo
[Root@vm-10-154-252-82 ~]$
[root@vm-10-154-252-82 ~] $cat List
10.154.252.46
10.154.252.47
10.154.252.48
10.154.252.49
[Root@vm-10-154-252-82 ~]$
[Root@vm-10-154-252-82 ~]$
[root@vm-10-154-252-82 ~] $pssh-i-H list ' uptime '
[1] 10:10:14 [SUCCESS] 10.154.252.46
10:10:14 up, 19:26, 2 users, load average:0.08, 0.02, 0.03
[2] 10:10:14 [SUCCESS] 10.154.252.49
10:10:14 up, 19:30, 1 user, Load average:0.00, 0.00, 0.00
[3] 10:10:14 [SUCCESS] 10.154.252.48
10:10:14 up, 20:49, 1 user, load average:0.13, 0.03, 0.01
[4] 10:10:14 [SUCCESS] 10.154.252.47
10:10:14 up, 19:59, 0 users, Load average:0.28, 0.08, 0.02
[Root@vm-10-154-252-82 ~]$
[Root@vm-10-154-252-82 ~]$
Pssh is Python line, easy to implement program scheduling concurrency.
The code is as follows |
Copy Code |
[root@vm-10-154-252-82 ~] $time pssh-i-h list ' sleep 3;uptime '
[1] 10:13:10 [SUCCESS] 10.154.252.46
10:13:10 up, 19:29, 2 users, Load average:0.00, 0.00, 0.01
[2] 10:13:10 [SUCCESS] 10.154.252.47
10:13:10 up, 20:02, 0 users, load average:0.01, 0.04, 0.00
[3] 10:13:10 [SUCCESS] 10.154.252.49
10:13:10 up, 19:33, 1 user, Load average:0.00, 0.00, 0.00
[4] 10:13:10 [SUCCESS] 10.154.252.48
10:13:10 up, 20:52, 1 user, load average:0.06, 0.04, 0.00
Real 0m3.175s
User 0m0.101s
SYS 0m0.038s |
Pssh's source code is in/usr/lib/python2.6/site-packages/psshlib
We can look at his master dispatch module, Managepy.
Import Select
Import Signal
Import Sys
Import threading
It contains these four modules. Select is used for scheduling, signal used to make timeouts, and threading is used to perform concurrent execution of multitasking. Pssh remote SSH execution, does not invoke Paramiko or fabric such as off-the-shelf SSH library, but directly with the subprocess invoke the system's SSH process.
The code is as follows |
Copy Code |
def clear_sigchld_handler (self):
Signal.signal (signal. SIGCHLD, Signal. SIG_DFL)
def set_sigchld_handler (self):
# Todo:find out whether SET_WAKEUP_FD still works if the default
# signal handler is used (I ' m pretty sure it doesn ' t work if the
# signal is ignored).
Signal.signal (signal. SIGCHLD, SELF.HANDLE_SIGCHLD)
# This should keep reads and writes from getting eintr.
If Hasattr (signal, ' siginterrupt '):
Signal.siginterrupt (signal. SIGCHLD, False)
def handle_sigchld (self, number, frame):
"" "Apparently we need a SIGCHLD handler to make set_wakeup_fd work." "
# Write to the signal pipe (a for Python <2.5, where the
# set_wakeup_fd method doesn ' t exist).
If SELF.IOMAP.WAKEUP_WRITEFD:
Os.write (SELF.IOMAP.WAKEUP_WRITEFD, "")
For task in self.running:
If Task.proc:
Task.proc.poll ()
# apparently some UNIX systems automatically resent the SIGCHLD
# handler to SIG_DFL. Reset it just in the case.
Self.set_sigchld_handler ()
def check_timeout (self):
"" "Kills Timed-out processes and returns the lowest time left." "
If Self.timeout <= 0:
Return None
Min_timeleft = None
For task in self.running:
Timeleft = self.timeout-task.elapsed ()
If Timeleft <= 0:
Task.timedout ()
Continue
If Min_timeleft is None or Timeleft < min_timeleft:
Min_timeleft = Timeleft
If Min_timeleft is None:
return 0
Else
Return Max (0, Min_timeleft) |
To resolve the logic of a host file
The code is as follows |
Copy Code |
def read_host_files (Paths, Default_user=none, Default_port=none):
"" "reads the given host files.
Returns a list of (host, port, user) triples.
"""
hosts = []
If paths:
For path in paths:
Hosts.extend (Read_host_file (path, Default_user=default_user))
Return to hosts
def read_host_file (Path, Default_user=none, Default_port=none):
"" "reads the given host file.
Lines are of the form:host[:p ORT] [login].
Returns a list of (host, port, user) triples.
"""
lines = []
f = Open (path)
For line in F:
Lines.append (Line.strip ())
F.close ()
hosts = []
For line in lines:
# Skip Blank lines or lines starting with #
line = Line.strip ()
If not line or Line.startswith (' # '):
Continue
Host, port, user = Parse_host_entry (line, Default_user, Default_port)
If host:
Hosts.append (host, port, user)
Return to hosts |
Let's take a look at the logic that executes the command.
The code is as follows |
Copy Code |
def start (self, nodenum, Iomap, writer, askpass_socket=none):
"" "starts the process and registers files with the iomap." "
Self.writer = writer
If writer:
Self.outfile, Self.errfile = Writer.open_files (self.pretty_host)
# Set up the environment.
Environ = Dict (Os.environ)
environ[' pssh_nodenum '] = str (nodenum)
environ[' pssh_host '] = Self.host
# Disable The GNOME Pop-up Password dialog and allow SSH to use
# askpass.py to get a provided password. If the module file is
# ASKPASS.PYC, we replace the extension.
environ[' ssh_askpass '] = Askpass_client.executable_path ()
If Askpass_socket:
environ[' pssh_askpass_socket '] = Askpass_socket
If Self.verbose:
environ[' pssh_askpass_verbose '] = ' 1 '
# Work around a mis-feature in ssh where it won ' t call Ssh_askpass
# if DISPLAY is unset.
If ' DISPLAY ' not in environ:
environ[' DISPLAY ' = ' pssh-gibberish '
# Create the subprocess. Since We carefully call set_cloexec () on
# All open files, we specify Close_fds=false.
Self.proc = Popen (Self.cmd, Stdin=pipe, Stdout=pipe, Stderr=pipe,
Close_fds=false, Preexec_fn=os.setsid, Env=environ)
Self.timestamp = Time.time ()
If Self.inputbuffer:
Self.stdin = Self.proc.stdin
Iomap.register_write (Self.stdin.fileno (), Self.handle_stdin)
Else
Self.proc.stdin.close ()
Self.stdout = Self.proc.stdout
Iomap.register_read (Self.stdout.fileno (), self.handle_stdout)
Self.stderr = Self.proc.stderr
Iomap.register_read (Self.stderr.fileno (), Self.handle_stderr) |
In fact, these two tools are not very satisfactory, or recommend the use of ansible and saltstack such a strong extensibility tool.
Of course still depends on your environment, how good how to!!!