diff --git a/.gitignore b/.gitignore deleted file mode 100644 index d2d6f36..0000000 --- a/.gitignore +++ /dev/null @@ -1,35 +0,0 @@ -*.py[cod] - -# C extensions -*.so - -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg -lib -lib64 - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage -.tox -nosetests.xml - -# Translations -*.mo - -# Mr Developer -.mr.developer.cfg -.project -.pydevproject diff --git a/README.md b/README.md deleted file mode 100644 index 23055ca..0000000 --- a/README.md +++ /dev/null @@ -1,126 +0,0 @@ -python-ssh -========== - -The Python based paralleling ssh tool, useful for batch executing ssh remote command against a bunch of servers. - -It has some features you may be interested: -* use compressed hostname ranges, it tool will expand for you -* get server list from file -* support regex match of output, useful to indentify which servers is you wanted. (for example: list servers installed openssl-1.0.1a, Heartbleed impacted !) -* able to use jumpbox, with ```--extra-arg='-At jumpbox-hostname ssh'``` -* max number of parallel threads control - - -TODO -========== -create a user friendly install package - - -Commandline Help -========== - -``` -Usage: python-ssh [ -p ] (-f filename | -r range) [ -l login_name ] command - -Options: - --version show program's version number and exit - -h, --help show this help message and exit - -p PARALLEL, --parallel=PARALLEL - max number of parallel threads ,default is 10 - -r RANGE, --range=RANGE - Range of nodes to operate on - -f FILENAME, --file=FILENAME - the host file which stores the host list - -l LOGIN_NAME, --login_name=LOGIN_NAME - Specifies the user to log in as on the remote machine. - This also may be specified on a per-host basis in the - configuration file - -X EXTRA_ARGUMENT, --extra-arg=EXTRA_ARGUMENT - Extra command-line argument. for example: -o - ConnectTimeOut=10 - -e PATTERN, --regexp=PATTERN - Use PATTERN as the pattern; useful to protect - patterns beginning with -. - -v, --invert-match Invert the sense of matching, to select non-matching - lines. - -Report any bugs to lichun.william@gmail.com -``` - -Hostname Ranges -============ -The utility include er.py for expanding range expressiong, for example -``` -www[01-99].google.com -db0[1-3].demonware.net -www[1-2].demonware.net,mysql01-9.mysql.com -``` - -``` -er www[1-2].demonware.net,mysql0[1-9].mysql.com -www2.demonware.net -mysql08.mysql.com -mysql02.mysql.com -mysql03.mysql.com -mysql04.mysql.com -mysql05.mysql.com -mysql06.mysql.com -mysql07.mysql.com -mysql09.mysql.com -www1.demonware.net -mysql01.mysql.com -``` - -help -``` -Usage: er expr1 [expr2 ...] - -Expand host ranges with given expressions - -positional arguments: - expr expressions to be expanded - -optional arguments: - -h, --help show this help message and exit - -v, --version show program's version number and exit - -s, --sort sort the out put? - -f, --shuffle shuffle list? - -d DELIMITER, --delimiter DELIMITER - delimiter of the output, default is space - -n, --newline same as --delimiter='\n' - -Report any bugs to lichun.william@gmail.com -``` - -Examples -============ -Executing ```uname``` on 123 servers with default parrelling thread of 10. - -```pssh -lwilliam -r www[001-123].github.com -- uname``` - -Check ```ntpd``` status, dry run, with maximun 2 executing simultaneously. - -```pssh -lroot -r db0[1-2].github.com,web2-9.github.com --dry-run -P 2 -- /etc/init.d/ntpd status``` - -``` - 1 of 10 : =============== db01.github.com =============== -ssh -l root -o StrictHostKeyChecking=no db01.github.com /etc/init.d/ntpd status - 2 of 10 : =============== db02.github.com =============== -ssh -l root -o StrictHostKeyChecking=no db02.github.com /etc/init.d/ntpd status - 3 of 10 : =============== web3.github.com =============== -ssh -l root -o StrictHostKeyChecking=no web3.github.com /etc/init.d/ntpd status - 4 of 10 : =============== web4.github.com =============== -ssh -l root -o StrictHostKeyChecking=no web4.github.com /etc/init.d/ntpd status - 5 of 10 : =============== web8.github.com =============== -ssh -l root -o StrictHostKeyChecking=no web8.github.com /etc/init.d/ntpd status - 6 of 10 : =============== web5.github.com =============== -ssh -l root -o StrictHostKeyChecking=no web5.github.com /etc/init.d/ntpd status - 7 of 10 : =============== web2.github.com =============== -ssh -l root -o StrictHostKeyChecking=no web2.github.com /etc/init.d/ntpd status - 8 of 10 : =============== web7.github.com =============== -ssh -l root -o StrictHostKeyChecking=no web7.github.com /etc/init.d/ntpd status - 9 of 10 : =============== web9.github.com =============== -ssh -l root -o StrictHostKeyChecking=no web9.github.com /etc/init.d/ntpd status - 10 of 10 : =============== web6.github.com =============== -ssh -l root -o StrictHostKeyChecking=no web6.github.com /etc/init.d/ntpd status -``` diff --git a/fonts/copse-regular-webfont.eot b/fonts/copse-regular-webfont.eot new file mode 100644 index 0000000..af1f5e6 Binary files /dev/null and b/fonts/copse-regular-webfont.eot differ diff --git a/fonts/copse-regular-webfont.svg b/fonts/copse-regular-webfont.svg new file mode 100644 index 0000000..1e920b5 --- /dev/null +++ b/fonts/copse-regular-webfont.svg @@ -0,0 +1,247 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Copyright c 2010 Daniel Rhatigansparkyultrasparkyorg with Reserved Font Name Copse +Designer : Daniel Rhatigan +Foundry : Daniel Rhatigan + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/copse-regular-webfont.ttf b/fonts/copse-regular-webfont.ttf new file mode 100644 index 0000000..434b208 Binary files /dev/null and b/fonts/copse-regular-webfont.ttf differ diff --git a/fonts/copse-regular-webfont.woff b/fonts/copse-regular-webfont.woff new file mode 100644 index 0000000..a9a0450 Binary files /dev/null and b/fonts/copse-regular-webfont.woff differ diff --git a/fonts/quattrocentosans-bold-webfont.eot b/fonts/quattrocentosans-bold-webfont.eot new file mode 100644 index 0000000..c041ed9 Binary files /dev/null and b/fonts/quattrocentosans-bold-webfont.eot differ diff --git a/fonts/quattrocentosans-bold-webfont.svg b/fonts/quattrocentosans-bold-webfont.svg new file mode 100644 index 0000000..fb162e9 --- /dev/null +++ b/fonts/quattrocentosans-bold-webfont.svg @@ -0,0 +1,247 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Copyright c 2011 Pablo Impallari wwwimpallaricomimpallarigmailcomCopyright c 2011 Igino Marini wwwikerncommailiginomarinicomCopyright c 2011 Brenda Gallo gbrenda1987gmailcomwith Reserved Font Name Quattrocento Sans +Designer : Pablo Impallari +Foundry : Pablo Impallari Igino Marini Brenda Gallo +Foundry URL : wwwimpallaricom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/quattrocentosans-bold-webfont.ttf b/fonts/quattrocentosans-bold-webfont.ttf new file mode 100644 index 0000000..7389c87 Binary files /dev/null and b/fonts/quattrocentosans-bold-webfont.ttf differ diff --git a/fonts/quattrocentosans-bold-webfont.woff b/fonts/quattrocentosans-bold-webfont.woff new file mode 100644 index 0000000..fc14168 Binary files /dev/null and b/fonts/quattrocentosans-bold-webfont.woff differ diff --git a/fonts/quattrocentosans-bolditalic-webfont.eot b/fonts/quattrocentosans-bolditalic-webfont.eot new file mode 100644 index 0000000..7c1aa7a Binary files /dev/null and b/fonts/quattrocentosans-bolditalic-webfont.eot differ diff --git a/fonts/quattrocentosans-bolditalic-webfont.svg b/fonts/quattrocentosans-bolditalic-webfont.svg new file mode 100644 index 0000000..9070a8b --- /dev/null +++ b/fonts/quattrocentosans-bolditalic-webfont.svg @@ -0,0 +1,248 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Copyright c 2011 Pablo Impallari wwwimpallaricomimpallarigmailcomCopyright c 2011 Igino Marini wwwikerncommailiginomarinicomCopyright c 2011 Brenda Gallo gbrenda1987gmailcomwith Reserved Font Name Quattrocento Sans +Designer : Pablo Impallari +Foundry : Pablo Impallari Igino Marini Brenda Gallo +Foundry URL : wwwimpallaricom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/quattrocentosans-bolditalic-webfont.ttf b/fonts/quattrocentosans-bolditalic-webfont.ttf new file mode 100644 index 0000000..9766a17 Binary files /dev/null and b/fonts/quattrocentosans-bolditalic-webfont.ttf differ diff --git a/fonts/quattrocentosans-bolditalic-webfont.woff b/fonts/quattrocentosans-bolditalic-webfont.woff new file mode 100644 index 0000000..c436da0 Binary files /dev/null and b/fonts/quattrocentosans-bolditalic-webfont.woff differ diff --git a/fonts/quattrocentosans-italic-webfont.eot b/fonts/quattrocentosans-italic-webfont.eot new file mode 100644 index 0000000..379b383 Binary files /dev/null and b/fonts/quattrocentosans-italic-webfont.eot differ diff --git a/fonts/quattrocentosans-italic-webfont.svg b/fonts/quattrocentosans-italic-webfont.svg new file mode 100644 index 0000000..b613779 --- /dev/null +++ b/fonts/quattrocentosans-italic-webfont.svg @@ -0,0 +1,247 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Copyright c 2011 Pablo Impallari wwwimpallaricomimpallarigmailcomCopyright c 2011 Igino Marini wwwikerncommailiginomarinicomCopyright c 2011 Brenda Gallo gbrenda1987gmailcomwith Reserved Font Name Quattrocento Sans +Designer : Pablo Impallari +Foundry : Pablo Impallari Igino Marini Brenda Gallo +Foundry URL : wwwimpallaricom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/quattrocentosans-italic-webfont.ttf b/fonts/quattrocentosans-italic-webfont.ttf new file mode 100644 index 0000000..c7ba47a Binary files /dev/null and b/fonts/quattrocentosans-italic-webfont.ttf differ diff --git a/fonts/quattrocentosans-italic-webfont.woff b/fonts/quattrocentosans-italic-webfont.woff new file mode 100644 index 0000000..3798881 Binary files /dev/null and b/fonts/quattrocentosans-italic-webfont.woff differ diff --git a/fonts/quattrocentosans-regular-webfont.eot b/fonts/quattrocentosans-regular-webfont.eot new file mode 100644 index 0000000..346db6f Binary files /dev/null and b/fonts/quattrocentosans-regular-webfont.eot differ diff --git a/fonts/quattrocentosans-regular-webfont.svg b/fonts/quattrocentosans-regular-webfont.svg new file mode 100644 index 0000000..3470924 --- /dev/null +++ b/fonts/quattrocentosans-regular-webfont.svg @@ -0,0 +1,247 @@ + + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Copyright c 2011 Pablo Impallari wwwimpallaricomimpallarigmailcomCopyright c 2011 Igino Marini wwwikerncommailiginomarinicomCopyright c 2011 Brenda Gallo gbrenda1987gmailcomwith Reserved Font Name Quattrocento Sans +Designer : Pablo Impallari +Foundry : Pablo Impallari Igino Marini Brenda Gallo +Foundry URL : wwwimpallaricom + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fonts/quattrocentosans-regular-webfont.ttf b/fonts/quattrocentosans-regular-webfont.ttf new file mode 100644 index 0000000..e414670 Binary files /dev/null and b/fonts/quattrocentosans-regular-webfont.ttf differ diff --git a/fonts/quattrocentosans-regular-webfont.woff b/fonts/quattrocentosans-regular-webfont.woff new file mode 100644 index 0000000..09ed324 Binary files /dev/null and b/fonts/quattrocentosans-regular-webfont.woff differ diff --git a/images/background.png b/images/background.png new file mode 100644 index 0000000..e57dd78 Binary files /dev/null and b/images/background.png differ diff --git a/images/body-background.png b/images/body-background.png new file mode 100644 index 0000000..dbe1a77 Binary files /dev/null and b/images/body-background.png differ diff --git a/images/bullet.png b/images/bullet.png new file mode 100644 index 0000000..732fa2f Binary files /dev/null and b/images/bullet.png differ diff --git a/images/hr.gif b/images/hr.gif new file mode 100644 index 0000000..a64b56c Binary files /dev/null and b/images/hr.gif differ diff --git a/images/octocat-logo.png b/images/octocat-logo.png new file mode 100644 index 0000000..8a2dd2a Binary files /dev/null and b/images/octocat-logo.png differ diff --git a/index.html b/index.html new file mode 100644 index 0000000..b25e68a --- /dev/null +++ b/index.html @@ -0,0 +1,189 @@ + + + + + + Python-ssh by williamjoy + + + + + + + + + + +
+

Python-ssh

+

parallel ssh execute over a cluster

+
+ + + +
+ +
+

+python-ssh

+ +

The Python based paralleling ssh tool, useful for batch executing ssh remote command against a bunch of servers.

+ +

It has some features you may be interested:

+ +
    +
  • use compressed hostname ranges, it tool will expand for you
  • +
  • get server list from file
  • +
  • support regex match of output, useful to indentify which servers is you wanted. (for example: list servers installed openssl-1.0.1a, Heartbleed impacted !)
  • +
  • able to use jumpbox, with --extra-arg='-At jumpbox-hostname ssh' +
  • +
  • max number of parallel threads control
  • +
+ +

+TODO

+ +

create a user friendly install package

+ +

+Commandline Help

+ +
Usage: python-ssh [ -p <max parallel thread number> ] (-f filename | -r range)     [ -l login_name ] command
+
+Options:
+  --version             show program's version number and exit
+  -h, --help            show this help message and exit
+  -p PARALLEL, --parallel=PARALLEL
+                        max number of parallel threads ,default is 10
+  -r RANGE, --range=RANGE
+                        Range of nodes to operate on
+  -f FILENAME, --file=FILENAME
+                        the host file which stores the host list
+  -l LOGIN_NAME, --login_name=LOGIN_NAME
+                        Specifies the user to log in as on the remote machine.
+                        This also may be specified on a per-host basis in the
+                        configuration file
+  -X EXTRA_ARGUMENT, --extra-arg=EXTRA_ARGUMENT
+                        Extra command-line argument. for example: -o
+                        ConnectTimeOut=10
+  -e PATTERN, --regexp=PATTERN
+                        Use PATTERN as the pattern;    useful to protect
+                        patterns beginning with -.
+  -v, --invert-match    Invert the sense of matching, to select non-matching
+                        lines.
+
+Report any bugs to lichun.william@gmail.com
+
+ +

+Hostname Ranges

+ +

The utility include er.py for expanding range expressiong, for example

+ +
www[01-99].google.com
+db0[1-3].demonware.net
+www[1-2].demonware.net,mysql01-9.mysql.com
+
+ +
er www[1-2].demonware.net,mysql0[1-9].mysql.com
+www2.demonware.net
+mysql08.mysql.com
+mysql02.mysql.com
+mysql03.mysql.com
+mysql04.mysql.com
+mysql05.mysql.com
+mysql06.mysql.com
+mysql07.mysql.com
+mysql09.mysql.com
+www1.demonware.net
+mysql01.mysql.com
+
+ +

help

+ +
Usage: er expr1 [expr2 ...]
+
+Expand host ranges with given expressions
+
+positional arguments:
+  expr                  expressions to be expanded
+
+optional arguments:
+  -h, --help            show this help message and exit
+  -v, --version         show program's version number and exit
+  -s, --sort            sort the out put?
+  -f, --shuffle         shuffle list?
+  -d DELIMITER, --delimiter DELIMITER
+                        delimiter of the output, default is space
+  -n, --newline         same as --delimiter='\n'
+
+Report any bugs to lichun.william@gmail.com
+
+ +

+Examples

+ +

Executing uname on 123 servers with default parrelling thread of 10.

+ +

pssh -lwilliam -r www[001-123].github.com -- uname

+ +

Check ntpd status, dry run, with maximun 2 executing simultaneously.

+ +

pssh -lroot -r db0[1-2].github.com,web2-9.github.com --dry-run -P 2 -- /etc/init.d/ntpd status

+ +
 1 of 10 : ===============  db01.github.com  ===============
+ssh -l root -o StrictHostKeyChecking=no db01.github.com /etc/init.d/ntpd status
+ 2 of 10 : ===============  db02.github.com  ===============
+ssh -l root -o StrictHostKeyChecking=no db02.github.com /etc/init.d/ntpd status
+ 3 of 10 : ===============  web3.github.com  ===============
+ssh -l root -o StrictHostKeyChecking=no web3.github.com /etc/init.d/ntpd status
+ 4 of 10 : ===============  web4.github.com  ===============
+ssh -l root -o StrictHostKeyChecking=no web4.github.com /etc/init.d/ntpd status
+ 5 of 10 : ===============  web8.github.com  ===============
+ssh -l root -o StrictHostKeyChecking=no web8.github.com /etc/init.d/ntpd status
+ 6 of 10 : ===============  web5.github.com  ===============
+ssh -l root -o StrictHostKeyChecking=no web5.github.com /etc/init.d/ntpd status
+ 7 of 10 : ===============  web2.github.com  ===============
+ssh -l root -o StrictHostKeyChecking=no web2.github.com /etc/init.d/ntpd status
+ 8 of 10 : ===============  web7.github.com  ===============
+ssh -l root -o StrictHostKeyChecking=no web7.github.com /etc/init.d/ntpd status
+ 9 of 10 : ===============  web9.github.com  ===============
+ssh -l root -o StrictHostKeyChecking=no web9.github.com /etc/init.d/ntpd status
+ 10 of 10 : ===============  web6.github.com  ===============
+ssh -l root -o StrictHostKeyChecking=no web6.github.com /etc/init.d/ntpd status
+
+
+ +
+ + + + + + \ No newline at end of file diff --git a/javascripts/main.js b/javascripts/main.js new file mode 100644 index 0000000..c57e54c --- /dev/null +++ b/javascripts/main.js @@ -0,0 +1,53 @@ +var sectionHeight = function() { + var total = $(window).height(), + $section = $('section').css('height','auto'); + + if ($section.outerHeight(true) < total) { + var margin = $section.outerHeight(true) - $section.height(); + $section.height(total - margin - 20); + } else { + $section.css('height','auto'); + } +} + +$(window).resize(sectionHeight); + +$(document).ready(function(){ + $("section h1, section h2").each(function(){ + $("nav ul").append("
  • " + $(this).text() + "
  • "); + $(this).attr("id",$(this).text().toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g,'')); + $("nav ul li:first-child a").parent().addClass("active"); + }); + + $("nav ul li").on("click", "a", function(event) { + var position = $($(this).attr("href")).offset().top - 190; + $("html, body").animate({scrollTop: position}, 400); + $("nav ul li a").parent().removeClass("active"); + $(this).parent().addClass("active"); + event.preventDefault(); + }); + + sectionHeight(); + + $('img').load(sectionHeight); +}); + +fixScale = function(doc) { + + var addEvent = 'addEventListener', + type = 'gesturestart', + qsa = 'querySelectorAll', + scales = [1, 1], + meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : []; + + function fix() { + meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1]; + doc.removeEventListener(type, fix, true); + } + + if ((meta = meta[meta.length - 1]) && addEvent in doc) { + fix(); + scales = [.25, 1.6]; + doc[addEvent](type, fix, true); + } +}; \ No newline at end of file diff --git a/params.json b/params.json new file mode 100644 index 0000000..d556480 --- /dev/null +++ b/params.json @@ -0,0 +1 @@ +{"name":"Python-ssh","tagline":"parallel ssh execute over a cluster","body":"python-ssh\r\n==========\r\n\r\nThe Python based paralleling ssh tool, useful for batch executing ssh remote command against a bunch of servers.\r\n\r\nIt has some features you may be interested:\r\n* use compressed hostname ranges, it tool will expand for you\r\n* get server list from file\r\n* support regex match of output, useful to indentify which servers is you wanted. (for example: list servers installed openssl-1.0.1a, Heartbleed impacted !) \r\n* able to use jumpbox, with ```--extra-arg='-At jumpbox-hostname ssh'```\r\n* max number of parallel threads control\r\n\r\n\r\nTODO\r\n==========\r\ncreate a user friendly install package\r\n\r\n\r\nCommandline Help\r\n==========\r\n\r\n```\r\nUsage: python-ssh [ -p ] (-f filename | -r range) [ -l login_name ] command\r\n\r\nOptions:\r\n --version show program's version number and exit\r\n -h, --help show this help message and exit\r\n -p PARALLEL, --parallel=PARALLEL\r\n max number of parallel threads ,default is 10\r\n -r RANGE, --range=RANGE\r\n Range of nodes to operate on\r\n -f FILENAME, --file=FILENAME\r\n the host file which stores the host list\r\n -l LOGIN_NAME, --login_name=LOGIN_NAME\r\n Specifies the user to log in as on the remote machine.\r\n This also may be specified on a per-host basis in the\r\n configuration file\r\n -X EXTRA_ARGUMENT, --extra-arg=EXTRA_ARGUMENT\r\n Extra command-line argument. for example: -o\r\n ConnectTimeOut=10\r\n -e PATTERN, --regexp=PATTERN\r\n Use PATTERN as the pattern; useful to protect\r\n patterns beginning with -.\r\n -v, --invert-match Invert the sense of matching, to select non-matching\r\n lines.\r\n\r\nReport any bugs to lichun.william@gmail.com\r\n```\r\n\r\nHostname Ranges\r\n============\r\nThe utility include er.py for expanding range expressiong, for example\r\n```\r\nwww[01-99].google.com\r\ndb0[1-3].demonware.net\r\nwww[1-2].demonware.net,mysql01-9.mysql.com\r\n```\r\n\r\n```\r\ner www[1-2].demonware.net,mysql0[1-9].mysql.com\r\nwww2.demonware.net\r\nmysql08.mysql.com\r\nmysql02.mysql.com\r\nmysql03.mysql.com\r\nmysql04.mysql.com\r\nmysql05.mysql.com\r\nmysql06.mysql.com\r\nmysql07.mysql.com\r\nmysql09.mysql.com\r\nwww1.demonware.net\r\nmysql01.mysql.com\r\n```\r\n\r\nhelp\r\n```\r\nUsage: er expr1 [expr2 ...]\r\n\r\nExpand host ranges with given expressions\r\n\r\npositional arguments:\r\n expr expressions to be expanded\r\n\r\noptional arguments:\r\n -h, --help show this help message and exit\r\n -v, --version show program's version number and exit\r\n -s, --sort sort the out put?\r\n -f, --shuffle shuffle list?\r\n -d DELIMITER, --delimiter DELIMITER\r\n delimiter of the output, default is space\r\n -n, --newline same as --delimiter='\\n'\r\n\r\nReport any bugs to lichun.william@gmail.com\r\n```\r\n\r\nExamples\r\n============\r\nExecuting ```uname``` on 123 servers with default parrelling thread of 10.\r\n\r\n```pssh -lwilliam -r www[001-123].github.com -- uname```\r\n\r\nCheck ```ntpd``` status, dry run, with maximun 2 executing simultaneously.\r\n\r\n```pssh -lroot -r db0[1-2].github.com,web2-9.github.com --dry-run -P 2 -- /etc/init.d/ntpd status```\r\n\r\n```\r\n 1 of 10 : =============== db01.github.com ===============\r\nssh -l root -o StrictHostKeyChecking=no db01.github.com /etc/init.d/ntpd status\r\n 2 of 10 : =============== db02.github.com ===============\r\nssh -l root -o StrictHostKeyChecking=no db02.github.com /etc/init.d/ntpd status\r\n 3 of 10 : =============== web3.github.com ===============\r\nssh -l root -o StrictHostKeyChecking=no web3.github.com /etc/init.d/ntpd status\r\n 4 of 10 : =============== web4.github.com ===============\r\nssh -l root -o StrictHostKeyChecking=no web4.github.com /etc/init.d/ntpd status\r\n 5 of 10 : =============== web8.github.com ===============\r\nssh -l root -o StrictHostKeyChecking=no web8.github.com /etc/init.d/ntpd status\r\n 6 of 10 : =============== web5.github.com ===============\r\nssh -l root -o StrictHostKeyChecking=no web5.github.com /etc/init.d/ntpd status\r\n 7 of 10 : =============== web2.github.com ===============\r\nssh -l root -o StrictHostKeyChecking=no web2.github.com /etc/init.d/ntpd status\r\n 8 of 10 : =============== web7.github.com ===============\r\nssh -l root -o StrictHostKeyChecking=no web7.github.com /etc/init.d/ntpd status\r\n 9 of 10 : =============== web9.github.com ===============\r\nssh -l root -o StrictHostKeyChecking=no web9.github.com /etc/init.d/ntpd status\r\n 10 of 10 : =============== web6.github.com ===============\r\nssh -l root -o StrictHostKeyChecking=no web6.github.com /etc/init.d/ntpd status\r\n```\r\n","google":"UA-50552473-1","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file diff --git a/src/er.py b/src/er.py deleted file mode 100755 index b6ad7eb..0000000 --- a/src/er.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python -#-*- coding = utf-8 -*- -''' the Parallel batch command running environment''' -''' - A tool for expend host range expressions - - Author : Wei Lichun - Create Date : Thu Apr 3 14:32:30 CST 2014 - Version : 1.3 -''' - -''' - - -This is free software; see the source for copying conditions. -There is NO warranty; not even for MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. - -''' -import sys -import argparse -import random - -import expand_range - -parser =argparse.ArgumentParser( - description = "Expand host ranges with given expressions", - usage ="%(prog)s expr1 [expr2 ...]", - epilog="Report any bugs to lichun.william@gmail.com", prog='er') -parser.add_argument("-s", "--sort", action="store_true", default=False, - dest="sort", help="sort the out put?") -parser.add_argument("-f", "--shuffle", action="store_true", default=False, - dest="shuffle", help="shuffle list?") -parser.add_argument("-c", "--compress", action="store_true", default=False, - dest="compress", help="Compress host list ?") -parser.add_argument("-d", "--delimiter", action="store", default=' ', - dest="delimiter", help="delimiter of the output, default is space") -parser.add_argument("-n", "--newline", action="store_const", dest="delimiter", - const='\n', help="same as --delimiter='\\n'") -parser.add_argument("expr", action="store", nargs='+', - help="expressions to be expanded") - -if __name__ == '__main__': - options =parser.parse_args() - expr = options.expr - results =expand_range.expand(",".join(expr)) - delimiter = options.delimiter.replace('\\t', '\t') - delimiter = delimiter.replace('\\n', '\n') - if(options.compress): - results=expand_range.compress(results) - if(options.sort): - results.sort() - elif(options.shuffle): - random.shuffle(results) - print(delimiter.join(results)) - diff --git a/src/expand_range.py b/src/expand_range.py deleted file mode 100644 index 346ed72..0000000 --- a/src/expand_range.py +++ /dev/null @@ -1,280 +0,0 @@ -#!/usr/local/bin/python -''' The List Host Library Python Version''' - -__license__ = """ - Copyright (c) 2010 Yahoo! Inc. All rights reserved. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. See accompanying LICENSE file. -""" - -''' -Author : William Wei -Create Date : Thu Apr 3 10:59:29 CST 2014 -Version : 0.1 - -This is free software; see the source for copying conditions. -There is NO warranty; not even for MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. - -Report bugs to lichun.william@gmail.com -''' - -''' Example: stnd0001-10,,couria.ash,stnab-ds01-04''' - -import re -import os -import sys -import operator -import logging -import imp - -global_plugins = {} - -SET_OPERATORS = ['-'] -#NUMBER_RANGE_RE_PATTERN=re.compile("^([_a-z.-]*([0-9_a-z.-]*[_a-z.-]+)?)?([0-9]+)-([0-9]+)((\.[a-z0-9_-]+)*.?)$",re.IGNORECASE) - -def expand(range_list, onepass=False): - """ - Expand a list of lists and set operators into a final host lists - >>> hostlists.expand(['foo[01-10]','-','foo[04-06]']) - ['foo09', 'foo08', 'foo07', 'foo02', 'foo01', 'foo03', 'foo10'] - >>> - """ - if isinstance(range_list, str): - range_list = [h.strip() for h in range_list.split(',')] - new_list = [] - set1 = None - operation = None - for item in range_list: - if set1 and operation: - set2 = expand_item(item) - new_list.append(list(set(set1).difference(set(set2)))) - set1 = None - operation = None - elif item in SET_OPERATORS and len(new_list): - set1 = new_list.pop() - operation = item - else: - expanded_item = expand_item(item, onepass = onepass) - new_list.append(expanded_item) - new_list2 = [] - for item in new_list: - new_list2 += item - return new_list2 - -def expand_item(range_list, onepass=False): - """ Expand a list of plugin:parameters into a list of hosts """ - #range_list=list(range_list) - # Find all the host list plugins - if 'basestring' not in dir(__builtins__): - # basestring is not in python3.x - basestring = str - pass - - if isinstance(range_list, basestring): - range_list = [range_list] - plugins = _get_plugins() - - # Iterate through our list - newlist = [] - found_plugin = False - for item in range_list: - # Is the item a plugin - temp = item.split(':') - if len(temp) > 1: - plugin = temp[0].lower() - # Do we have a plugin that matches the passed plugin - if plugin in plugins.keys(): - # Call the plugin - item = None - if multiple_names(plugins[plugin]): - newlist += plugins[plugin].expand( - ':'.join(temp[1:]).strip(':'), name = plugin) - else: - newlist += plugins[plugin].expand( - ':'.join(temp[1:]).strip(':')) - found_plugin = True - else: - # This should probably just be an exception - sys.stderr.write( - 'plugin', plugin, - 'not found, valid plugins are:', ','.join(plugins.keys()), - ) - else: - # Default to running through the range plugin - item = None - newlist += plugins['range'].expand(temp[0]) - if item: - newlist.append(item) - # Recurse back through ourselves incase a plugin returns a value that - # needs to be parsed - # by another plugin. For example a dns resource that has an address that - # points to a load balancer vip that may container a number of hosts that - # need to be looked up via the load_balancer plugin. - if found_plugin and not onepass: - newlist = expand_item(newlist) - return newlist - -def multikeysort(items, columns): - - comparers = [ - ((operator.itemgetter(col[1:].strip()), -1) if col.startswith('-') else (operator.itemgetter(col.strip()), 1)) for col in columns - ] - - def comparer(left, right): - for fn, mult in comparers: - try: - result = cmp_compat(fn(left), fn(right)) - except KeyError: - return 0 - if result: - return mult * result - else: - return 0 - try: - # noinspection PyArgumentList - return sorted(items, cmp=comparer) - except TypeError: - # Python 3 removed the cmp parameter - import functools - return sorted(items, key=functools.cmp_to_key(comparer)) - -def compress(hostnames): - """ - Compress a list of host into a more compact range representation - """ - domain_dict = {} - result=[] - for host in hostnames: - if '.' in host: - domain = '.'.join(host.split('.')[1:]) - else: - domain = '' - try: - domain_dict[domain].append(host) - except KeyError: - domain_dict[domain]=[host] - domains = list(domain_dict.keys()) - domains.sort() - for domain in domains: - hosts=compress_domain(domain_dict[domain]) - result += hosts - return result - - -def compress_domain(hostnames): - """ - Compress a list of hosts in a domain into a more compact representation - """ - hostnames.sort() - prev_dict = { 'prefix': "", 'suffix': '', 'number': 0 } - items = [] - items_block = [] - new_hosts = [] - for host in hostnames: - #print re.match(r"([^0-9]+)(\d+)(.+).?",sys.argv[1]).groups() - try: - parsed_dict = re.match( - r"(?P[^0-9]+)(?P\d+)(?P.*).?", - host - ).groupdict() - # To generate the range we need the entries sorted numerically - # but to ensure we don't loose any leading 0s we don't want to - # replace the number parameter that is a string with the leading - # 0s. - parsed_dict['number_int'] = int(parsed_dict['number']) - new_hosts.append(parsed_dict) - except AttributeError: - if '.' not in host: - host += '.' - parsed_dict = { 'host': compress([host])[0].strip('.') } - else: - parsed_dict = { 'host': host } - new_hosts.append(parsed_dict) - new_hosts = multikeysort(new_hosts, ['prefix', 'number_int']) - for parsed_dict in new_hosts: - if 'host' in parsed_dict.keys() or parsed_dict['prefix'] != prev_dict['prefix'] or parsed_dict['suffix'] != prev_dict['suffix'] or int(parsed_dict['number']) != int(prev_dict['number']) + 1: - if len(items_block): - items.append(items_block) - items_block = [parsed_dict] - else: - items_block.append(parsed_dict) - prev_dict = parsed_dict - items.append(items_block) - result = [] - for item in items: - if len(item): - if len(item) == 1 and 'host' in item[0].keys(): - result.append(item[0]['host']) - elif len(item) == 1: - result.append( - '%s%s%s' % ( - item[0]['prefix'], item[0]['number'], item[0]['suffix'] - ) - ) - else: - common_number_prefix = os.path.commonprefix([item[0]['number'], item[-1]['number']]) - result.append( - '%s[%s-%s]%s' % ( - item[0]['prefix'] + common_number_prefix , item[0]['number'][len(common_number_prefix):], item[-1]['number'][len(common_number_prefix):], item[0]['suffix'] - ) - ) - return result - -def cmp_compat(a, b): - return (a > b) - (a < b) - -def _get_plugins(): - """ Find all the hostlists plugins """ - plugins = global_plugins - pluginlist = [] - plugin_path = [ - os.path.dirname(__file__), - '~/.hostlists', - #'~/lib/hostlists', - #os.path.join(sys.prefix, 'hostlists'), - #os.path.join(sys.prefix, 'site-packages/hostlists'), - #os.path.join(sys.prefix, 'dist-packages/hostlists'), - #os.path.join(sys.prefix, 'lib/hostlists'), - #'/usr/lib/hostlists', - ] + sys.path - for directory in plugin_path: - if os.path.isdir(os.path.join(directory, 'plugins')): - templist = os.listdir(os.path.join(directory, 'plugins')) - for item in templist: - pluginlist.append( - os.path.join(os.path.join(directory, 'plugins'), item) - ) - pluginlist.sort() - # Create a dict mapping the plugin name to the plugin method - for item in pluginlist: - if item.endswith('.py'): - module_file = open(item) - try: - mod = imp.load_module( - 'hostlists_plugins_%s' % os.path.basename(item[:-3]), - module_file, - item, - ('.py', 'r', imp.PY_SOURCE) - ) - names = mod.name() - if isinstance(names, str): - names = [names] - for name in names: - if name not in plugins.keys(): - plugins[name.lower()] = mod - except: - # Error in module import, probably a plugin bug - logging.debug( - "Plugin import failed %s:" % item - ) - if module_file: - module_file.close() - return plugins diff --git a/src/plugins/range.py b/src/plugins/range.py deleted file mode 100644 index 978c593..0000000 --- a/src/plugins/range.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python -""" hostlists plugin to get hosts from a file """ - -__license__ = """ - Copyright (c) 2010-2013 Yahoo! Inc. All rights reserved. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. See accompanying LICENSE file. -""" - - -def name(): - """ - Plugin name - """ - return 'range' - - -def expand(value): - """ - Use Plugin to expand the value - """ - return expand_item(value) - - -def block_to_list(block): - """ Convert a range block into a numeric list - input "1-3,17,19-20" - output=[1,2,3,17,19,20] - """ - block+=',' - result=[] - val='' - in_range=False - for letter in block: - if letter in [',','-']: - if in_range: - val2=val - val2_len=len(val2) - #result+=range(int(val1),int(val2)+1) - for value in range(int(val1),int(val2)+1): - if val1.startswith('0'): - result.append(str(value).zfill(val2_len)) - else: - result.append(str(value)) - val='' - val1=None - in_range=False - else: - val1=val - val1_len=len(val1) - val='' - if letter == ',': - if val1 is not None: - result.append(val1.zfill(val1_len)) - else: - in_range=True - else: - val+=letter - return result - - -def expand_item(item): - result=[] - in_block=False - pre_block='' - for count in range(0,len(item)): - letter=item[count] - if letter == '[': - in_block=True - block='' - elif letter == ']' and in_block: - in_block=False - for value in block_to_list(block): - result.append('%s%s%s'% (pre_block,value,item[count+1:])) - elif in_block: - block+=letter - elif not in_block: - pre_block += letter - if len(result): - return result - else: - return [item] diff --git a/src/ppaste.py b/src/ppaste.py deleted file mode 100755 index 9784137..0000000 --- a/src/ppaste.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python -#-*- coding = utf-8 -*- -''' -Report any bugs to lichun.william@gmail.com - -This is free software; see the source for copying conditions. -There is NO warranty; not even for MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. - -Report any bugs to lichun.william@gmail.com -''' -import subprocess -import optparse -import sys -import socket - -import process_thread -import get_host_list - -parser=optparse.OptionParser(usage='%prog --template filename1 filename2', - version='%prog 1.2', - epilog="Report any bugs to lichun.william@gmail.com", prog='ppaste') -parser.add_option("-t","--template" ,action="store",type="string", - dest="template",help="the template") -parser.add_option("-i","--hostname-to-ip",action="store_true", - default=False,dest="to_ip",help="change host name to ip address") - -def host_to_ip(hostname=""): - return socket.gethostbyaddr(hostname)[2][0] - -(options,filenames)=parser.parse_args() - -if (not options.template): - print ('no template specified') - parser.print_help() - sys.exit(-2) - -if (not filenames): - print ('no filename specified') - parser.print_help() - sys.exit(-2) - - - -if __name__ == '__main__': - array1=get_host_list.get_hosts_from_file(filenames[0]) - array2=get_host_list.get_hosts_from_file(filenames[1]) - for line in zip( array1,array2): - if(options.to_ip): - print options.template % (host_to_ip(line[0]),host_to_ip(line[1])) - else: - print options.template % (line[0],line[1]) diff --git a/src/process_thread.py b/src/process_thread.py deleted file mode 100644 index 1fa3106..0000000 --- a/src/process_thread.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr//bin/python3 -#-*- coding = utf-8 -*- -''' The List Host Library Python Version''' - -''' -Author : Wei Lichun -Create Date : Sat Sep 10 18:58:31 CST 2011 -Version : 0.1 - -This is free software; see the source for copying conditions. -There is NO warranty; not even for MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. - -Report bugs to lichun.william@gmail.com -''' -import threading -import subprocess -import os -import sys -if sys.version_info > (3,0): - from queue import Queue -else: - from Queue import Queue - -class Task(threading.Thread): - def __init__(self,key,cmd,finish_pool,semaphore): - threading.Thread.__init__(self) - self.key=key - self.cmd=cmd - self.done_queue=finish_pool - self.stdout=None - self.semaphore=semaphore - - def run(self): - p=subprocess.Popen(self.cmd,stderr=subprocess.STDOUT, - stdout=subprocess.PIPE,stdin=None,shell=False) - self.stdout=p.communicate()[0] - self.done_queue.put(self) - self.semaphore.release() - - def get_cmd(): - return self.cmd - -class TaskGroup(threading.Thread): - def __init__(self,parallel=10): - threading.Thread.__init__(self) - self.done_queue=Queue() - self.task_queue=Queue() - self.semaphore=threading.Semaphore(parallel) - - def add_task(self,key,cmd): - task=Task(key,cmd,self.done_queue,self.semaphore) - self.task_queue.put(task) - def run(self): - while(not self.task_queue.empty()): - t=self.task_queue.get() - self.semaphore.acquire() - t.start() diff --git a/src/python-shell.py b/src/python-shell.py deleted file mode 100755 index abc0c70..0000000 --- a/src/python-shell.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python -#-*- coding = utf-8 -*- - -''' -Report any bugs to lichun.william@gmail.com - - -This is free software; see the source for copying conditions. -There is NO warranty; not even for MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. - -Report any bugs to lichun.william@gmail.com -''' -import subprocess -import optparse -import sys -import copy -import shlex -import signal - -import process_thread -import query_hosts - -parser=optparse.OptionParser(usage="%prog -f filename",version='%prog 1.2', - epilog="Report any bugs to lichun.william@gmail.com", prog='pshell') -parser.add_option("-p","--parallel",action="store",type="int",dest="parallel", - default=10,help="max number of parallel threads ,default is 10") -parser.add_option("-f","--file",action="store",type="string",dest="filename", - help="the host file which stores the host list") - - -(options,command)=parser.parse_args() - -filename=options.filename -parallel=options.parallel - -if(filename): - lines=query_hosts.get_hosts_from_file(filename) -else: - print ('No Hosts Returned') - sys.exit(-3) - -def signal_handler(signal, frame): - print 'Ctrl+C Caught, Exiting..' - sys.exit(1) - -if __name__ == '__main__': - tasks=[] - task_group=process_thread.TaskGroup(parallel) - signal.signal(signal.SIGINT, signal_handler) - print lines - for line in lines: - task_group.add_task(line,shlex.split(line)) - - task_group.start() - size=len(lines) - print size - index=0 - while(index - Create Date : Thu Sep 8 21:58:04 CST 2011 - Version : 1.3 - Recent Changes: - support max parallel thread argument - support login_name argument - support regex pattern filter, invert match -''' - -''' - - -This is free software; see the source for copying conditions. -There is NO warranty; not even for MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. - -''' -from os import getlogin -import subprocess -import argparse -import sys -import copy -import re -import signal -import getpass -import random - -import process_thread -import query_hosts - - -parser=argparse.ArgumentParser( - usage="%(prog)s [ -P ] (-f filename | -r range)\ - [ -l login_name ] command", - epilog="Report any bugs to lichun.william@gmail.com", prog='python-ssh') -parser.add_argument("-V", "--verbose", action="store_true", default=False, - dest="verbose_mode", help="print more logs") -parser.add_argument("-d", "--dry-run", action="store_true", default=False, - dest="dry_run", help="only print command, without really running it") -parser.add_argument("-p", "--password", action="store_true", default=False, - dest="use_password", help="use ssh password?") -parser.add_argument("-P", "--parallel", type=int, dest="parallel", default=10, - help="max number of parallel threads , default is 10") -parser.add_argument("-r", "--range" , action="store", nargs='+', - dest="range", help="Range of nodes to operate on") -parser.add_argument("-s", "--shuffle", action="store_true", default=False, - dest="shuffle", help="Shuffle the server list?") -parser.add_argument("-f", "--file", action="store", - dest="filename", help="the host file which stores the host list") -parser.add_argument("-l", "--login_name", action="store", - dest="login_name", default=getlogin(), - help="Specifies the user to log in as on the remote machine.\ - This also may be specified on a per-host basis in the configuration file") -parser.add_argument("-X", "--extra-arg", action="store", dest="extra_argument", - help="Extra command-line argument. for example: -o ConnectTimeOut=10") -parser.add_argument("-e", "--regexp", metavar="PATTERN", action="store", - dest="pattern", - help="Use PATTERN as the pattern;\ - useful to protect patterns beginning with -.") -parser.add_argument("--invert-match", - action="store_false", dest="invert", default=True, - help="Invert the sense of matching, to select non-matching lines.") - -parser.add_argument("command", nargs='+', - help="command line to be executed on remote hosts") - - -options=parser.parse_args() - -command=options.command - -filename=options.filename -login_name=options.login_name -pattern=options.pattern -parallel=options.parallel -extra_argument=options.extra_argument - -if (not command): - parser.error ('command argument is required') -if (options.filename): - hostnames=query_hosts.get_hosts_from_file(options.filename) -elif(options.range): - hostnames=query_hosts.get_hosts_from_range(','.join(options.range)) -else: - parser.error ('one filename or range is required') - -if (options.use_password): - password=getpass.getpass(prompt="%s@$REMOTE's password:" % login_name) - -def signal_handler(signal, frame): - print('Ctrl+C Caught, Exiting..') - sys.exit(1) - -def insert(l, arg): - if (isinstance(arg, str)): - items=arg.split() - elif (isinstance(arg, list)): - items=arg - items.reverse() - for e in items: - l.insert(0, e) - return l - -def append(l, arg): - if (isinstance(arg, str)): - items=arg.split() - elif (isinstance(arg, list)): - items=arg - for e in items: - l.append(e) - return l - - -if __name__ == '__main__': - tasks=[] - if(not hostnames): - print('No Hosts Returned') - sys.exit(-3) - prefix = [] - suffix = [] - if (extra_argument): - insert(prefix, extra_argument) - insert(prefix, "-o StrictHostKeyChecking=no") - - if(login_name): - insert(prefix, '-l %s' % login_name) - insert(prefix, 'ssh') - if(options.use_password): - insert(prefix, 'sshpass -p %s' % password) - if(options.dry_run==True): - insert(prefix, 'echo') - task_group=process_thread.TaskGroup(parallel) - if(options.shuffle): - random.shuffle(hostnames) - for host in hostnames: - ssh_command=copy.copy(prefix) - append(ssh_command, host) - append(ssh_command, command) - task_group.add_task(host, ssh_command) - - signal.signal(signal.SIGINT, signal_handler) - task_group.start() - size=len(hostnames) - index=0 - if(pattern): - compiled_pattern=re.compile(pattern) - while(index -Create Date : Sat Sep 10 18:58:31 CST 2011 -Version : 0.2 - -This is free software; see the source for copying conditions. -There is NO warranty; not even for MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. - -Report bugs to lichun.william@gmail.com -''' -import expand_range - -def get_hosts_from_file(filename=''): - """This function reads content from file to generate a list of lines. - This function removes comments delimited by '#', ingores empty - lines, and leading and trailing whitespace. - Returns: - a list of hosts - """ - f=open(filename) - result=[] - for line in f: - line=line.replace('\n','') - if line: - idx = line.find('#') - if idx >= 0: - line = line[:idx].strip() - if line: - result.append( line ) - return result - -def get_hosts_from_range(range=''): - if(range): - return expand_range.expand(range) - else: - return [] diff --git a/stylesheets/normalize.css b/stylesheets/normalize.css new file mode 100644 index 0000000..bc2ba93 --- /dev/null +++ b/stylesheets/normalize.css @@ -0,0 +1,459 @@ +/* normalize.css 2012-02-07T12:37 UTC - http://github.com/necolas/normalize.css */ +/* ============================================================================= + HTML5 display definitions + ========================================================================== */ +/* + * Corrects block display not defined in IE6/7/8/9 & FF3 + */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section, +summary { + display: block; +} + +/* + * Corrects inline-block display not defined in IE6/7/8/9 & FF3 + */ +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +/* + * Prevents modern browsers from displaying 'audio' without controls + */ +audio:not([controls]) { + display: none; +} + +/* + * Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4 + * Known issue: no IE6 support + */ +[hidden] { + display: none; +} + +/* ============================================================================= + Base + ========================================================================== */ +/* + * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units + * http://clagnut.com/blog/348/#c790 + * 2. Prevents iOS text size adjust after orientation change, without disabling user zoom + * www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/ + */ +html { + font-size: 100%; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -ms-text-size-adjust: 100%; + /* 2 */ +} + +/* + * Addresses font-family inconsistency between 'textarea' and other form elements. + */ +html, +button, +input, +select, +textarea { + font-family: sans-serif; +} + +/* + * Addresses margins handled incorrectly in IE6/7 + */ +body { + margin: 0; +} + +/* ============================================================================= + Links + ========================================================================== */ +/* + * Addresses outline displayed oddly in Chrome + */ +a:focus { + outline: thin dotted; +} + +/* + * Improves readability when focused and also mouse hovered in all browsers + * people.opera.com/patrickl/experiments/keyboard/test + */ +a:hover, +a:active { + outline: 0; +} + +/* ============================================================================= + Typography + ========================================================================== */ +/* + * Addresses font sizes and margins set differently in IE6/7 + * Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5 + */ +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +h2 { + font-size: 1.5em; + margin: 0.83em 0; +} + +h3 { + font-size: 1.17em; + margin: 1em 0; +} + +h4 { + font-size: 1em; + margin: 1.33em 0; +} + +h5 { + font-size: 0.83em; + margin: 1.67em 0; +} + +h6 { + font-size: 0.75em; + margin: 2.33em 0; +} + +/* + * Addresses styling not present in IE7/8/9, S5, Chrome + */ +abbr[title] { + border-bottom: 1px dotted; +} + +/* + * Addresses style set to 'bolder' in FF3+, S4/5, Chrome +*/ +b, +strong { + font-weight: bold; +} + +blockquote { + margin: 1em 40px; +} + +/* + * Addresses styling not present in S5, Chrome + */ +dfn { + font-style: italic; +} + +/* + * Addresses styling not present in IE6/7/8/9 + */ +mark { + background: #ff0; + color: #000; +} + +/* + * Addresses margins set differently in IE6/7 + */ +p, +pre { + margin: 1em 0; +} + +/* + * Corrects font family set oddly in IE6, S4/5, Chrome + * en.wikipedia.org/wiki/User:Davidgothberg/Test59 + */ +pre, +code, +kbd, +samp { + font-family: monospace, serif; + _font-family: 'courier new', monospace; + font-size: 1em; +} + +/* + * 1. Addresses CSS quotes not supported in IE6/7 + * 2. Addresses quote property not supported in S4 + */ +/* 1 */ +q { + quotes: none; +} + +/* 2 */ +q:before, +q:after { + content: ''; + content: none; +} + +small { + font-size: 75%; +} + +/* + * Prevents sub and sup affecting line-height in all browsers + * gist.github.com/413930 + */ +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* ============================================================================= + Lists + ========================================================================== */ +/* + * Addresses margins set differently in IE6/7 + */ +dl, +menu, +ol, +ul { + margin: 1em 0; +} + +dd { + margin: 0 0 0 40px; +} + +/* + * Addresses paddings set differently in IE6/7 + */ +menu, +ol, +ul { + padding: 0 0 0 40px; +} + +/* + * Corrects list images handled incorrectly in IE7 + */ +nav ul, +nav ol { + list-style: none; + list-style-image: none; +} + +/* ============================================================================= + Embedded content + ========================================================================== */ +/* + * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3 + * 2. Improves image quality when scaled in IE7 + * code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/ + */ +img { + border: 0; + /* 1 */ + -ms-interpolation-mode: bicubic; + /* 2 */ +} + +/* + * Corrects overflow displayed oddly in IE9 + */ +svg:not(:root) { + overflow: hidden; +} + +/* ============================================================================= + Figures + ========================================================================== */ +/* + * Addresses margin not present in IE6/7/8/9, S5, O11 + */ +figure { + margin: 0; +} + +/* ============================================================================= + Forms + ========================================================================== */ +/* + * Corrects margin displayed oddly in IE6/7 + */ +form { + margin: 0; +} + +/* + * Define consistent border, margin, and padding + */ +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/* + * 1. Corrects color not being inherited in IE6/7/8/9 + * 2. Corrects text not wrapping in FF3 + * 3. Corrects alignment displayed oddly in IE6/7 + */ +legend { + border: 0; + /* 1 */ + padding: 0; + white-space: normal; + /* 2 */ + *margin-left: -7px; + /* 3 */ +} + +/* + * 1. Corrects font size not being inherited in all browsers + * 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome + * 3. Improves appearance and consistency in all browsers + */ +button, +input, +select, +textarea { + font-size: 100%; + /* 1 */ + margin: 0; + /* 2 */ + vertical-align: baseline; + /* 3 */ + *vertical-align: middle; + /* 3 */ +} + +/* + * Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet + */ +button, +input { + line-height: normal; + /* 1 */ +} + +/* + * 1. Improves usability and consistency of cursor style between image-type 'input' and others + * 2. Corrects inability to style clickable 'input' types in iOS + * 3. Removes inner spacing in IE7 without affecting normal text inputs + * Known issue: inner spacing remains in IE6 + */ +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + /* 1 */ + -webkit-appearance: button; + /* 2 */ + *overflow: visible; + /* 3 */ +} + +/* + * Re-set default cursor for disabled elements + */ +button[disabled], +input[disabled] { + cursor: default; +} + +/* + * 1. Addresses box sizing set to content-box in IE8/9 + * 2. Removes excess padding in IE8/9 + * 3. Removes excess padding in IE7 + Known issue: excess padding remains in IE6 + */ +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + /* 1 */ + padding: 0; + /* 2 */ + *height: 13px; + /* 3 */ + *width: 13px; + /* 3 */ +} + +/* + * 1. Addresses appearance set to searchfield in S5, Chrome + * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof) + */ +input[type="search"] { + -webkit-appearance: textfield; + /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + /* 2 */ + box-sizing: content-box; +} + +/* + * Removes inner padding and search cancel button in S5, Chrome on OS X + */ +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +/* + * Removes inner padding and border in FF3+ + * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/ + */ +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/* + * 1. Removes default vertical scrollbar in IE6/7/8/9 + * 2. Improves readability and alignment in all browsers + */ +textarea { + overflow: auto; + /* 1 */ + vertical-align: top; + /* 2 */ +} + +/* ============================================================================= + Tables + ========================================================================== */ +/* + * Remove most spacing between table cells + */ +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/stylesheets/pygment_trac.css b/stylesheets/pygment_trac.css new file mode 100644 index 0000000..62fd970 --- /dev/null +++ b/stylesheets/pygment_trac.css @@ -0,0 +1,70 @@ +.highlight .hll { background-color: #404040 } +.highlight { color: #d0d0d0 } +.highlight .c { color: #999999; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .g { color: #d0d0d0 } /* Generic */ +.highlight .k { color: #6ab825; font-weight: normal } /* Keyword */ +.highlight .l { color: #d0d0d0 } /* Literal */ +.highlight .n { color: #d0d0d0 } /* Name */ +.highlight .o { color: #d0d0d0 } /* Operator */ +.highlight .x { color: #d0d0d0 } /* Other */ +.highlight .p { color: #d0d0d0 } /* Punctuation */ +.highlight .cm { color: #999999; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #cd2828; font-weight: normal } /* Comment.Preproc */ +.highlight .c1 { color: #999999; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #e50808; font-weight: normal; background-color: #520000 } /* Comment.Special */ +.highlight .gd { color: #d22323 } /* Generic.Deleted */ +.highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #d22323 } /* Generic.Error */ +.highlight .gh { color: #ffffff; font-weight: normal } /* Generic.Heading */ +.highlight .gi { color: #589819 } /* Generic.Inserted */ +.highlight .go { color: #cccccc } /* Generic.Output */ +.highlight .gp { color: #aaaaaa } /* Generic.Prompt */ +.highlight .gs { color: #d0d0d0; font-weight: normal } /* Generic.Strong */ +.highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */ +.highlight .gt { color: #d22323 } /* Generic.Traceback */ +.highlight .kc { color: #6ab825; font-weight: normal } /* Keyword.Constant */ +.highlight .kd { color: #6ab825; font-weight: normal } /* Keyword.Declaration */ +.highlight .kn { color: #6ab825; font-weight: normal } /* Keyword.Namespace */ +.highlight .kp { color: #6ab825 } /* Keyword.Pseudo */ +.highlight .kr { color: #6ab825; font-weight: normal } /* Keyword.Reserved */ +.highlight .kt { color: #6ab825; font-weight: normal } /* Keyword.Type */ +.highlight .ld { color: #d0d0d0 } /* Literal.Date */ +.highlight .m { color: #3677a9 } /* Literal.Number */ +.highlight .s { color: #ff8 } /* Literal.String */ +.highlight .na { color: #bbbbbb } /* Name.Attribute */ +.highlight .nb { color: #24909d } /* Name.Builtin */ +.highlight .nc { color: #447fcf; text-decoration: underline } /* Name.Class */ +.highlight .no { color: #40ffff } /* Name.Constant */ +.highlight .nd { color: #ffa500 } /* Name.Decorator */ +.highlight .ni { color: #d0d0d0 } /* Name.Entity */ +.highlight .ne { color: #bbbbbb } /* Name.Exception */ +.highlight .nf { color: #447fcf } /* Name.Function */ +.highlight .nl { color: #d0d0d0 } /* Name.Label */ +.highlight .nn { color: #447fcf; text-decoration: underline } /* Name.Namespace */ +.highlight .nx { color: #d0d0d0 } /* Name.Other */ +.highlight .py { color: #d0d0d0 } /* Name.Property */ +.highlight .nt { color: #6ab825;} /* Name.Tag */ +.highlight .nv { color: #40ffff } /* Name.Variable */ +.highlight .ow { color: #6ab825; font-weight: normal } /* Operator.Word */ +.highlight .w { color: #666666 } /* Text.Whitespace */ +.highlight .mf { color: #3677a9 } /* Literal.Number.Float */ +.highlight .mh { color: #3677a9 } /* Literal.Number.Hex */ +.highlight .mi { color: #3677a9 } /* Literal.Number.Integer */ +.highlight .mo { color: #3677a9 } /* Literal.Number.Oct */ +.highlight .sb { color: #ff8 } /* Literal.String.Backtick */ +.highlight .sc { color: #ff8 } /* Literal.String.Char */ +.highlight .sd { color: #ff8 } /* Literal.String.Doc */ +.highlight .s2 { color: #ff8 } /* Literal.String.Double */ +.highlight .se { color: #ff8 } /* Literal.String.Escape */ +.highlight .sh { color: #ff8 } /* Literal.String.Heredoc */ +.highlight .si { color: #ff8 } /* Literal.String.Interpol */ +.highlight .sx { color: #ffa500 } /* Literal.String.Other */ +.highlight .sr { color: #ff8 } /* Literal.String.Regex */ +.highlight .s1 { color: #ff8 } /* Literal.String.Single */ +.highlight .ss { color: #ff8 } /* Literal.String.Symbol */ +.highlight .bp { color: #24909d } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #40ffff } /* Name.Variable.Class */ +.highlight .vg { color: #40ffff } /* Name.Variable.Global */ +.highlight .vi { color: #40ffff } /* Name.Variable.Instance */ +.highlight .il { color: #3677a9 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/stylesheets/styles.css b/stylesheets/styles.css new file mode 100644 index 0000000..980ee2b --- /dev/null +++ b/stylesheets/styles.css @@ -0,0 +1,1010 @@ +/* +Leap Day for GitHub Pages +by Matt Graham +*/ +@font-face { + font-family: 'Quattrocento Sans'; + src: url("../fonts/quattrocentosans-bold-webfont.eot"); + src: url("../fonts/quattrocentosans-bold-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/quattrocentosans-bold-webfont.woff") format("woff"), url("../fonts/quattrocentosans-bold-webfont.ttf") format("truetype"), url("../fonts/quattrocentosans-bold-webfont.svg#QuattrocentoSansBold") format("svg"); + font-weight: bold; + font-style: normal; +} + +@font-face { + font-family: 'Quattrocento Sans'; + src: url("../fonts/quattrocentosans-bolditalic-webfont.eot"); + src: url("../fonts/quattrocentosans-bolditalic-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/quattrocentosans-bolditalic-webfont.woff") format("woff"), url("../fonts/quattrocentosans-bolditalic-webfont.ttf") format("truetype"), url("../fonts/quattrocentosans-bolditalic-webfont.svg#QuattrocentoSansBoldItalic") format("svg"); + font-weight: bold; + font-style: italic; +} + +@font-face { + font-family: 'Quattrocento Sans'; + src: url("../fonts/quattrocentosans-italic-webfont.eot"); + src: url("../fonts/quattrocentosans-italic-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/quattrocentosans-italic-webfont.woff") format("woff"), url("../fonts/quattrocentosans-italic-webfont.ttf") format("truetype"), url("../fonts/quattrocentosans-italic-webfont.svg#QuattrocentoSansItalic") format("svg"); + font-weight: normal; + font-style: italic; +} + +@font-face { + font-family: 'Quattrocento Sans'; + src: url("../fonts/quattrocentosans-regular-webfont.eot"); + src: url("../fonts/quattrocentosans-regular-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/quattrocentosans-regular-webfont.woff") format("woff"), url("../fonts/quattrocentosans-regular-webfont.ttf") format("truetype"), url("../fonts/quattrocentosans-regular-webfont.svg#QuattrocentoSansRegular") format("svg"); + font-weight: normal; + font-style: normal; +} + +@font-face { + font-family: 'Copse'; + src: url("../fonts/copse-regular-webfont.eot"); + src: url("../fonts/copse-regular-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/copse-regular-webfont.woff") format("woff"), url("../fonts/copse-regular-webfont.ttf") format("truetype"), url("../fonts/copse-regular-webfont.svg#CopseRegular") format("svg"); + font-weight: normal; + font-style: normal; +} + +/* normalize.css 2012-02-07T12:37 UTC - http://github.com/necolas/normalize.css */ +/* ============================================================================= + HTML5 display definitions + ========================================================================== */ +/* + * Corrects block display not defined in IE6/7/8/9 & FF3 + */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section, +summary { + display: block; +} + +/* + * Corrects inline-block display not defined in IE6/7/8/9 & FF3 + */ +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +/* + * Prevents modern browsers from displaying 'audio' without controls + */ +audio:not([controls]) { + display: none; +} + +/* + * Addresses styling for 'hidden' attribute not present in IE7/8/9, FF3, S4 + * Known issue: no IE6 support + */ +[hidden] { + display: none; +} + +/* ============================================================================= + Base + ========================================================================== */ +/* + * 1. Corrects text resizing oddly in IE6/7 when body font-size is set using em units + * http://clagnut.com/blog/348/#c790 + * 2. Prevents iOS text size adjust after orientation change, without disabling user zoom + * www.456bereastreet.com/archive/201012/controlling_text_size_in_safari_for_ios_without_disabling_user_zoom/ + */ +html { + font-size: 100%; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -ms-text-size-adjust: 100%; + /* 2 */ +} + +/* + * Addresses font-family inconsistency between 'textarea' and other form elements. + */ +html, +button, +input, +select, +textarea { + font-family: sans-serif; +} + +/* + * Addresses margins handled incorrectly in IE6/7 + */ +body { + margin: 0; +} + +/* ============================================================================= + Links + ========================================================================== */ +/* + * Addresses outline displayed oddly in Chrome + */ +a:focus { + outline: thin dotted; +} + +/* + * Improves readability when focused and also mouse hovered in all browsers + * people.opera.com/patrickl/experiments/keyboard/test + */ +a:hover, +a:active { + outline: 0; +} + +/* ============================================================================= + Typography + ========================================================================== */ +/* + * Addresses font sizes and margins set differently in IE6/7 + * Addresses font sizes within 'section' and 'article' in FF4+, Chrome, S5 + */ +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +h2 { + font-size: 1.5em; + margin: 0.83em 0; +} + +h3 { + font-size: 1.17em; + margin: 1em 0; +} + +h4 { + font-size: 1em; + margin: 1.33em 0; +} + +h5 { + font-size: 0.83em; + margin: 1.67em 0; +} + +h6 { + font-size: 0.75em; + margin: 2.33em 0; +} + +/* + * Addresses styling not present in IE7/8/9, S5, Chrome + */ +abbr[title] { + border-bottom: 1px dotted; +} + +/* + * Addresses style set to 'bolder' in FF3+, S4/5, Chrome +*/ +b, +strong { + font-weight: bold; +} + +blockquote { + margin: 1em 40px; +} + +/* + * Addresses styling not present in S5, Chrome + */ +dfn { + font-style: italic; +} + +/* + * Addresses styling not present in IE6/7/8/9 + */ +mark { + background: #ff0; + color: #000; +} + +/* + * Addresses margins set differently in IE6/7 + */ +p, +pre { + margin: 1em 0; +} + +/* + * Corrects font family set oddly in IE6, S4/5, Chrome + * en.wikipedia.org/wiki/User:Davidgothberg/Test59 + */ +pre, +code, +kbd, +samp { + font-family: monospace, serif; + _font-family: 'courier new', monospace; + font-size: 1em; +} + +/* + * 1. Addresses CSS quotes not supported in IE6/7 + * 2. Addresses quote property not supported in S4 + */ +/* 1 */ +q { + quotes: none; +} + +/* 2 */ +q:before, +q:after { + content: ''; + content: none; +} + +small { + font-size: 75%; +} + +/* + * Prevents sub and sup affecting line-height in all browsers + * gist.github.com/413930 + */ +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* ============================================================================= + Lists + ========================================================================== */ +/* + * Addresses margins set differently in IE6/7 + */ +dl, +menu, +ol, +ul { + margin: 1em 0; +} + +dd { + margin: 0 0 0 40px; +} + +/* + * Addresses paddings set differently in IE6/7 + */ +menu, +ol, +ul { + padding: 0 0 0 40px; +} + +/* + * Corrects list images handled incorrectly in IE7 + */ +nav ul, +nav ol { + list-style: none; + list-style-image: none; +} + +/* ============================================================================= + Embedded content + ========================================================================== */ +/* + * 1. Removes border when inside 'a' element in IE6/7/8/9, FF3 + * 2. Improves image quality when scaled in IE7 + * code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/ + */ +img { + border: 0; + /* 1 */ + -ms-interpolation-mode: bicubic; + /* 2 */ +} + +/* + * Corrects overflow displayed oddly in IE9 + */ +svg:not(:root) { + overflow: hidden; +} + +/* ============================================================================= + Figures + ========================================================================== */ +/* + * Addresses margin not present in IE6/7/8/9, S5, O11 + */ +figure { + margin: 0; +} + +/* ============================================================================= + Forms + ========================================================================== */ +/* + * Corrects margin displayed oddly in IE6/7 + */ +form { + margin: 0; +} + +/* + * Define consistent border, margin, and padding + */ +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/* + * 1. Corrects color not being inherited in IE6/7/8/9 + * 2. Corrects text not wrapping in FF3 + * 3. Corrects alignment displayed oddly in IE6/7 + */ +legend { + border: 0; + /* 1 */ + padding: 0; + white-space: normal; + /* 2 */ + *margin-left: -7px; + /* 3 */ +} + +/* + * 1. Corrects font size not being inherited in all browsers + * 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome + * 3. Improves appearance and consistency in all browsers + */ +button, +input, +select, +textarea { + font-size: 100%; + /* 1 */ + margin: 0; + /* 2 */ + vertical-align: baseline; + /* 3 */ + *vertical-align: middle; + /* 3 */ +} + +/* + * Addresses FF3/4 setting line-height on 'input' using !important in the UA stylesheet + */ +button, +input { + line-height: normal; + /* 1 */ +} + +/* + * 1. Improves usability and consistency of cursor style between image-type 'input' and others + * 2. Corrects inability to style clickable 'input' types in iOS + * 3. Removes inner spacing in IE7 without affecting normal text inputs + * Known issue: inner spacing remains in IE6 + */ +button, +input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + /* 1 */ + -webkit-appearance: button; + /* 2 */ + *overflow: visible; + /* 3 */ +} + +/* + * Re-set default cursor for disabled elements + */ +button[disabled], +input[disabled] { + cursor: default; +} + +/* + * 1. Addresses box sizing set to content-box in IE8/9 + * 2. Removes excess padding in IE8/9 + * 3. Removes excess padding in IE7 + Known issue: excess padding remains in IE6 + */ +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + /* 1 */ + padding: 0; + /* 2 */ + *height: 13px; + /* 3 */ + *width: 13px; + /* 3 */ +} + +/* + * 1. Addresses appearance set to searchfield in S5, Chrome + * 2. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof) + */ +input[type="search"] { + -webkit-appearance: textfield; + /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + /* 2 */ + box-sizing: content-box; +} + +/* + * Removes inner padding and search cancel button in S5, Chrome on OS X + */ +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +/* + * Removes inner padding and border in FF3+ + * www.sitepen.com/blog/2008/05/14/the-devils-in-the-details-fixing-dojos-toolbar-buttons/ + */ +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/* + * 1. Removes default vertical scrollbar in IE6/7/8/9 + * 2. Improves readability and alignment in all browsers + */ +textarea { + overflow: auto; + /* 1 */ + vertical-align: top; + /* 2 */ +} + +/* ============================================================================= + Tables + ========================================================================== */ +/* + * Remove most spacing between table cells + */ +table { + border-collapse: collapse; + border-spacing: 0; +} + +body { + font: 14px/22px "Quattrocento Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #666; + font-weight: 300; + margin: 0px; + padding: 0px 0 20px 0px; + background: url(../images/body-background.png) #eae6d1; +} + +h1, h2, h3, h4, h5, h6 { + color: #333; + margin: 0 0 10px; +} + +p, ul, ol, table, pre, dl { + margin: 0 0 20px; +} + +h1, h2, h3 { + line-height: 1.1; +} + +h1 { + font-size: 28px; +} + +h2 { + font-size: 24px; + color: #393939; +} + +h3, h4, h5, h6 { + color: #666666; +} + +h3 { + font-size: 18px; + line-height: 24px; +} + +a { + color: #3399cc; + font-weight: 400; + text-decoration: none; +} + +a small { + font-size: 11px; + color: #666; + margin-top: -0.6em; + display: block; +} + +ul { + list-style-image: url("../images/bullet.png"); +} + +strong { + font-weight: bold; + color: #333; +} + +.wrapper { + width: 650px; + margin: 0 auto; + position: relative; +} + +section img { + max-width: 100%; +} + +blockquote { + border-left: 1px solid #ffcc00; + margin: 0; + padding: 0 0 0 20px; + font-style: italic; +} + +code { + font-family: "Lucida Sans", Monaco, Bitstream Vera Sans Mono, Lucida Console, Terminal; + font-size: 13px; + color: #efefef; + text-shadow: 0px 1px 0px #000; + margin: 0 4px; + padding: 2px 6px; + background: #333; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + -o-border-radius: 2px; + -ms-border-radius: 2px; + -khtml-border-radius: 2px; + border-radius: 2px; +} + +pre { + padding: 8px 15px; + background: #333333; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + -o-border-radius: 3px; + -ms-border-radius: 3px; + -khtml-border-radius: 3px; + border-radius: 3px; + border: 1px solid #c7c7c7; + overflow: auto; + overflow-y: hidden; +} +pre code { + margin: 0px; + padding: 0px; +} + +table { + width: 100%; + border-collapse: collapse; +} + +th { + text-align: left; + padding: 5px 10px; + border-bottom: 1px solid #e5e5e5; + color: #444; +} + +td { + text-align: left; + padding: 5px 10px; + border-bottom: 1px solid #e5e5e5; + border-right: 1px solid #ffcc00; +} +td:first-child { + border-left: 1px solid #ffcc00; +} + +hr { + border: 0; + outline: none; + height: 11px; + background: transparent url("../images/hr.gif") center center repeat-x; + margin: 0 0 20px; +} + +dt { + color: #444; + font-weight: 700; +} + +header { + padding: 25px 20px 40px 20px; + margin: 0; + position: fixed; + top: 0; + left: 0; + right: 0; + width: 100%; + text-align: center; + background: url(../images/background.png) #4276b6; + -moz-box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.75); + -webkit-box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.75); + -o-box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.75); + box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.75); + z-index: 99; + -webkit-font-smoothing: antialiased; + min-height: 76px; +} +header h1 { + font: 40px/48px "Copse", "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #f3f3f3; + text-shadow: 0px 2px 0px #235796; + margin: 0px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + -ms-text-overflow: ellipsis; +} +header p { + color: #d8d8d8; + text-shadow: rgba(0, 0, 0, 0.2) 0 1px 0; + font-size: 18px; + margin: 0px; +} + +#banner { + z-index: 100; + left: 0; + right: 50%; + height: 50px; + margin-right: -382px; + position: fixed; + top: 115px; + background: #ffcc00; + border: 1px solid #f0b500; + -moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25); + -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25); + -o-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25); + box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.25); + -moz-border-radius: 0px 2px 2px 0px; + -webkit-border-radius: 0px 2px 2px 0px; + -o-border-radius: 0px 2px 2px 0px; + -ms-border-radius: 0px 2px 2px 0px; + -khtml-border-radius: 0px 2px 2px 0px; + border-radius: 0px 2px 2px 0px; + padding-right: 10px; +} +#banner .button { + border: 1px solid #dba500; + background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffe788), color-stop(100%, #ffce38)); + background: -webkit-linear-gradient(#ffe788, #ffce38); + background: -moz-linear-gradient(#ffe788, #ffce38); + background: -o-linear-gradient(#ffe788, #ffce38); + background: -ms-linear-gradient(#ffe788, #ffce38); + background: linear-gradient(#ffe788, #ffce38); + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + -o-border-radius: 2px; + -ms-border-radius: 2px; + -khtml-border-radius: 2px; + border-radius: 2px; + -moz-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.4), 0px 1px 1px rgba(0, 0, 0, 0.1); + -webkit-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.4), 0px 1px 1px rgba(0, 0, 0, 0.1); + -o-box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.4), 0px 1px 1px rgba(0, 0, 0, 0.1); + box-shadow: inset 0px 1px 0px rgba(255, 255, 255, 0.4), 0px 1px 1px rgba(0, 0, 0, 0.1); + background-color: #FFE788; + margin-left: 5px; + padding: 10px 12px; + margin-top: 6px; + line-height: 14px; + font-size: 14px; + color: #333; + font-weight: bold; + display: inline-block; + text-align: center; +} +#banner .button:hover { + background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffe788), color-stop(100%, #ffe788)); + background: -webkit-linear-gradient(#ffe788, #ffe788); + background: -moz-linear-gradient(#ffe788, #ffe788); + background: -o-linear-gradient(#ffe788, #ffe788); + background: -ms-linear-gradient(#ffe788, #ffe788); + background: linear-gradient(#ffe788, #ffe788); + background-color: #ffeca0; +} +#banner .fork { + position: fixed; + left: 50%; + margin-left: -325px; + padding: 10px 12px; + margin-top: 6px; + line-height: 14px; + font-size: 14px; + background-color: #FFE788; +} +#banner .downloads { + float: right; + margin: 0 45px 0 0; +} +#banner .downloads span { + float: left; + line-height: 52px; + font-size: 90%; + color: #9d7f0d; + text-transform: uppercase; + text-shadow: rgba(255, 255, 255, 0.2) 0 1px 0; +} +#banner ul { + list-style: none; + height: 40px; + padding: 0; + float: left; + margin-left: 10px; +} +#banner ul li { + display: inline; +} +#banner ul li a.button { + background-color: #FFE788; +} +#banner #logo { + position: absolute; + height: 36px; + width: 36px; + right: 7px; + top: 7px; + display: block; + background: url(../images/octocat-logo.png); +} + +section { + width: 590px; + padding: 30px 30px 50px 30px; + margin: 20px 0; + margin-top: 190px; + position: relative; + background: #fbfbfb; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + -o-border-radius: 3px; + -ms-border-radius: 3px; + -khtml-border-radius: 3px; + border-radius: 3px; + border: 1px solid #cbcbcb; + -moz-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.09), inset 0px 0px 2px 2px rgba(255, 255, 255, 0.5), inset 0 0 5px 5px rgba(255, 255, 255, 0.4); + -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.09), inset 0px 0px 2px 2px rgba(255, 255, 255, 0.5), inset 0 0 5px 5px rgba(255, 255, 255, 0.4); + -o-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.09), inset 0px 0px 2px 2px rgba(255, 255, 255, 0.5), inset 0 0 5px 5px rgba(255, 255, 255, 0.4); + box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.09), inset 0px 0px 2px 2px rgba(255, 255, 255, 0.5), inset 0 0 5px 5px rgba(255, 255, 255, 0.4); +} + +small { + font-size: 12px; +} + +nav { + width: 230px; + position: fixed; + top: 220px; + left: 50%; + margin-left: -580px; + text-align: right; +} +nav ul { + list-style: none; + list-style-image: none; + font-size: 14px; + line-height: 24px; +} +nav ul li { + padding: 5px 0px; + line-height: 16px; +} +nav ul li.tag-h1 { + font-size: 1.2em; +} +nav ul li.tag-h1 a { + font-weight: bold; + color: #333; +} +nav ul li.tag-h2 + .tag-h1 { + margin-top: 10px; +} +nav ul a { + color: #666; +} +nav ul a:hover { + color: #999; +} + +footer { + width: 180px; + position: fixed; + left: 50%; + margin-left: -530px; + bottom: 20px; + text-align: right; + line-height: 16px; +} + +@media print, screen and (max-width: 1060px) { + div.wrapper { + width: auto; + margin: 0; + } + + nav { + display: none; + } + + header, section, footer { + float: none; + } + header h1, section h1, footer h1 { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + -ms-text-overflow: ellipsis; + } + + #banner { + width: 100%; + } + #banner .downloads { + margin-right: 60px; + } + #banner #logo { + margin-right: 15px; + } + + section { + border: 1px solid #e5e5e5; + border-width: 1px 0; + padding: 20px auto; + margin: 190px auto 20px; + max-width: 600px; + } + + footer { + text-align: center; + margin: 20px auto; + position: relative; + left: auto; + bottom: auto; + width: auto; + } +} +@media print, screen and (max-width: 720px) { + body { + word-wrap: break-word; + } + + header { + padding: 20px 20px; + margin: 0; + } + header h1 { + font-size: 32px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + -ms-text-overflow: ellipsis; + } + header p { + display: none; + } + + #banner { + top: 80px; + } + #banner .fork { + float: left; + display: inline-block; + margin-left: 0px; + position: fixed; + left: 20px; + } + + section { + margin-top: 130px; + margin-bottom: 0px; + width: auto; + } + + header ul, header p.view { + position: static; + } +} +@media print, screen and (max-width: 480px) { + header { + position: relative; + padding: 5px 0px; + min-height: 0px; + } + header h1 { + font-size: 24px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + -o-text-overflow: ellipsis; + -ms-text-overflow: ellipsis; + } + + section { + margin-top: 5px; + } + + #banner { + display: none; + } + + header ul { + display: none; + } +} +@media print { + body { + padding: 0.4in; + font-size: 12pt; + color: #444; + } +} +@media print, screen and (max-height: 680px) { + footer { + text-align: center; + margin: 20px auto; + position: relative; + left: auto; + bottom: auto; + width: auto; + } +} +@media print, screen and (max-height: 480px) { + nav { + display: none; + } + + footer { + text-align: center; + margin: 20px auto; + position: relative; + left: auto; + bottom: auto; + width: auto; + } +} diff --git a/test/sample_hosts.txt b/test/sample_hosts.txt deleted file mode 100644 index fbba667..0000000 --- a/test/sample_hosts.txt +++ /dev/null @@ -1,18 +0,0 @@ -# this is a sample file of a hosts file -# as you can see, the host file syntax supports -# comments and whitespace removal -# hosts can be specified as names or - -192.168.2.1 -127.0.0.1 - - 127.0.0.1 -# here is a comment -mycomputer #comment! -mylaptop ############### - - # offset comment - -# trailing whitespace -> - - # f u l l diff --git a/test/test.sh b/test/test.sh deleted file mode 100644 index 1b26b2b..0000000 --- a/test/test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -python ../src/python-ssh.py -f sample_hosts.txt -- uname -a