Revision 2c30e9d7
b/lib/utils.py | ||
---|---|---|
32 | 32 |
import socket |
33 | 33 |
import tempfile |
34 | 34 |
import shutil |
35 |
from errno import ENOENT, ENOTDIR, EISDIR, EEXIST |
|
35 |
from errno import ENOENT, ENOTDIR, EISDIR, EEXIST, EADDRNOTAVAIL, ECONNREFUSED
|
|
36 | 36 |
|
37 | 37 |
from ganeti import logger |
38 | 38 |
from ganeti import errors |
... | ... | |
786 | 786 |
" output: %s" % (result.cmd, result.fail_reason, result.output)) |
787 | 787 |
|
788 | 788 |
return _ParseIpOutput(result.output) |
789 |
|
|
790 |
|
|
791 |
def TcpPing(source, target, port, timeout=10, live_port_needed=True): |
|
792 |
"""Simple ping implementation using TCP connect(2). |
|
793 |
|
|
794 |
Try to do a TCP connect(2) from the specified source IP to the specified |
|
795 |
target IP and the specified target port. If live_port_needed is set to true, |
|
796 |
requires the remote end to accept the connection. The timeout is specified |
|
797 |
in seconds and defaults to 10 seconds |
|
798 |
|
|
799 |
""" |
|
800 |
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
|
801 |
|
|
802 |
sucess = False |
|
803 |
|
|
804 |
try: |
|
805 |
sock.bind((source, 0)) |
|
806 |
except socket.error, (errcode, errstring): |
|
807 |
if errcode == EADDRNOTAVAIL: |
|
808 |
success = False |
|
809 |
|
|
810 |
sock.settimeout(timeout) |
|
811 |
|
|
812 |
try: |
|
813 |
sock.connect((target, port)) |
|
814 |
sock.close() |
|
815 |
success = True |
|
816 |
except socket.timeout: |
|
817 |
success = False |
|
818 |
except socket.error, (errcode, errstring): |
|
819 |
success = (not live_port_needed) and (errcode == ECONNREFUSED) |
|
820 |
|
|
821 |
return success |
b/test/ganeti.utils_unittest.py | ||
---|---|---|
27 | 27 |
import tempfile |
28 | 28 |
import os.path |
29 | 29 |
import md5 |
30 |
import socket |
|
31 |
from errno import EADDRNOTAVAIL |
|
30 | 32 |
|
31 | 33 |
import ganeti |
32 | 34 |
from ganeti.utils import IsProcessAlive, Lock, Unlock, RunCmd, \ |
33 | 35 |
RemoveFile, CheckDict, MatchNameComponent, FormatUnit, \ |
34 | 36 |
ParseUnit, AddAuthorizedKey, RemoveAuthorizedKey, \ |
35 |
ShellQuote, ShellQuoteArgs, _ParseIpOutput |
|
37 |
ShellQuote, ShellQuoteArgs, _ParseIpOutput, TcpPing
|
|
36 | 38 |
from ganeti.errors import LockError, UnitParseError |
37 | 39 |
|
40 |
|
|
38 | 41 |
class TestIsProcessAlive(unittest.TestCase): |
39 | 42 |
"""Testing case for IsProcessAlive""" |
40 | 43 |
def setUp(self): |
... | ... | |
467 | 470 |
self._test(output, ['127.0.0.1', '10.0.0.1', '1.2.3.4']) |
468 | 471 |
|
469 | 472 |
|
473 |
class TestTcpPing(unittest.TestCase): |
|
474 |
"""Testcase for TCP version of ping - against listen(2)ing port""" |
|
475 |
|
|
476 |
def setUp(self): |
|
477 |
self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
|
478 |
self.listener.bind(("127.0.0.1", 0)) |
|
479 |
self.listenerport = self.listener.getsockname()[1] |
|
480 |
self.listener.listen(1) |
|
481 |
|
|
482 |
def tearDown(self): |
|
483 |
self.listener.shutdown(socket.SHUT_RDWR) |
|
484 |
del self.listener |
|
485 |
del self.listenerport |
|
486 |
|
|
487 |
def testTcpPingToLocalHostAccept(self): |
|
488 |
self.assert_(TcpPing("127.0.0.1", |
|
489 |
"127.0.0.1", |
|
490 |
self.listenerport, |
|
491 |
timeout=10, |
|
492 |
live_port_needed=True), |
|
493 |
"failed to connect to test listener") |
|
494 |
|
|
495 |
|
|
496 |
class TestTcpPingDeaf(unittest.TestCase): |
|
497 |
"""Testcase for TCP version of ping - against non listen(2)ing port""" |
|
498 |
|
|
499 |
def setUp(self): |
|
500 |
self.deaflistener = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |
|
501 |
self.deaflistener.bind(("127.0.0.1", 0)) |
|
502 |
self.deaflistenerport = self.deaflistener.getsockname()[1] |
|
503 |
|
|
504 |
def tearDown(self): |
|
505 |
del self.deaflistener |
|
506 |
del self.deaflistenerport |
|
507 |
|
|
508 |
def testTcpPingToLocalHostAcceptDeaf(self): |
|
509 |
self.failIf(TcpPing("127.0.0.1", |
|
510 |
"127.0.0.1", |
|
511 |
self.deaflistenerport, |
|
512 |
timeout=10, # timeout for blocking operations |
|
513 |
live_port_needed=True), # need successful connect(2) |
|
514 |
"successfully connected to deaf listener") |
|
515 |
|
|
516 |
def testTcpPingToLocalHostNoAccept(self): |
|
517 |
self.assert_(TcpPing("127.0.0.1", |
|
518 |
"127.0.0.1", |
|
519 |
self.deaflistenerport, |
|
520 |
timeout=10, # timeout for blocking operations |
|
521 |
live_port_needed=False), # ECONNREFUSED is OK |
|
522 |
"failed to ping alive host on deaf port") |
|
523 |
|
|
524 |
|
|
470 | 525 |
if __name__ == '__main__': |
471 | 526 |
unittest.main() |
Also available in: Unified diff