sauce 0.12.2 → 0.12.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/support/sauce_connect +39 -30
- metadata +4 -4
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.12.
|
1
|
+
0.12.3
|
data/support/sauce_connect
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
from __future__ import with_statement
|
4
4
|
|
5
5
|
# TODO:
|
6
|
-
# * ?? Use "-o StrictHostKeyChecking no"
|
7
6
|
# * Move to REST API v1
|
8
7
|
# * windows: SSH link healthcheck (PuTTY session file hack?)
|
9
8
|
# * Daemonizing
|
@@ -11,7 +10,6 @@ from __future__ import with_statement
|
|
11
10
|
# * issue: unix: null file descriptors causes Expect script to fail
|
12
11
|
# * Renew tunnel lease (backend not implemented)
|
13
12
|
# * Check tunnel machine ports are open (backend not implemented)
|
14
|
-
#
|
15
13
|
|
16
14
|
import os
|
17
15
|
import sys
|
@@ -39,7 +37,7 @@ except ImportError:
|
|
39
37
|
import simplejson as json # Python 2.5 dependency
|
40
38
|
|
41
39
|
NAME = "sauce_connect"
|
42
|
-
RELEASE =
|
40
|
+
RELEASE = 21
|
43
41
|
DISPLAY_VERSION = "%s release %s" % (NAME, RELEASE)
|
44
42
|
PRODUCT_NAME = u"Sauce Connect"
|
45
43
|
VERSIONS_URL = "http://saucelabs.com/versions.json"
|
@@ -352,11 +350,13 @@ class ReverseSSHError(Exception):
|
|
352
350
|
|
353
351
|
class ReverseSSH(object):
|
354
352
|
|
355
|
-
def __init__(self, tunnel, host, ports, tunnel_ports,
|
353
|
+
def __init__(self, tunnel, host, ports, tunnel_ports,
|
354
|
+
use_ssh_config=False, debug=False):
|
356
355
|
self.tunnel = tunnel
|
357
356
|
self.host = host
|
358
357
|
self.ports = ports
|
359
358
|
self.tunnel_ports = tunnel_ports
|
359
|
+
self.use_ssh_config = use_ssh_config
|
360
360
|
self.debug = debug
|
361
361
|
|
362
362
|
self.proc = None
|
@@ -375,12 +375,8 @@ class ReverseSSH(object):
|
|
375
375
|
ssh_config_file = os.path.join(os.environ['HOME'], ".ssh", "config")
|
376
376
|
if os.path.exists(ssh_config_file):
|
377
377
|
logger.debug("Found %s" % ssh_config_file)
|
378
|
-
|
379
|
-
|
380
|
-
if os.path.exists(ssh_known_hosts):
|
381
|
-
if not os.path.isfile(ssh_known_hosts) or os.path.islink(ssh_known_hosts):
|
382
|
-
logger.debug("SSH known_hosts file (%s) is not a regular file "
|
383
|
-
% ssh_known_hosts)
|
378
|
+
if self.use_ssh_config:
|
379
|
+
logger.warn("Using local SSH config")
|
384
380
|
|
385
381
|
@property
|
386
382
|
def _dash_Rs(self):
|
@@ -390,27 +386,25 @@ class ReverseSSH(object):
|
|
390
386
|
return dash_Rs
|
391
387
|
|
392
388
|
def get_plink_command(self):
|
389
|
+
"""Return the Windows SSH command."""
|
393
390
|
verbosity = "-v" if self.debug else ""
|
394
391
|
return ("plink\plink %s -l %s -pw %s -N %s %s"
|
395
392
|
% (verbosity, self.tunnel.user, self.tunnel.password,
|
396
393
|
self._dash_Rs, self.tunnel.host))
|
397
394
|
|
398
395
|
def get_expect_script(self):
|
396
|
+
"""Return the Unix SSH command."""
|
399
397
|
wait = "wait"
|
400
398
|
if is_openbsd: # using 'wait;' hangs the script on OpenBSD
|
401
399
|
wait = "wait -nowait;sleep 1" # hack
|
402
400
|
|
403
401
|
verbosity = "-v" if self.debug else "-q"
|
402
|
+
config_file = "" if self.use_ssh_config else "-F /dev/null"
|
404
403
|
host_ip = socket.gethostbyname(self.tunnel.host)
|
405
404
|
script = (
|
406
|
-
"spawn ssh-
|
407
|
-
% (verbosity, self.tunnel.
|
408
|
-
|
409
|
-
"spawn ssh %s -p 22 -l %s -o ServerAliveInterval=%s -N %s %s;"
|
410
|
-
% (verbosity, self.tunnel.user, HEALTH_CHECK_INTERVAL,
|
411
|
-
self._dash_Rs, self.tunnel.host) +
|
412
|
-
'expect \\"Are you sure you want to continue connecting'
|
413
|
-
' (yes/no)?\\";send yes\\r;'
|
405
|
+
"spawn ssh %s %s -p 22 -l %s -o ServerAliveInterval=%s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -N %s %s;"
|
406
|
+
% (verbosity, config_file, self.tunnel.user,
|
407
|
+
HEALTH_CHECK_INTERVAL, self._dash_Rs, self.tunnel.host) +
|
414
408
|
"expect *password:;send -- %s\\r;" % self.tunnel.password +
|
415
409
|
"expect -timeout -1 timeout")
|
416
410
|
return script
|
@@ -539,7 +533,7 @@ def peace_out(tunnel=None, returncode=0, atexit=False):
|
|
539
533
|
logger.info("\ Exiting /")
|
540
534
|
raise SystemExit(returncode)
|
541
535
|
else:
|
542
|
-
logger.debug("
|
536
|
+
logger.debug("-- fin --")
|
543
537
|
|
544
538
|
|
545
539
|
def setup_signal_handler(tunnel, options):
|
@@ -632,7 +626,7 @@ def check_domains(domains):
|
|
632
626
|
sys.stderr.write(
|
633
627
|
"Error: Domain contains illegal character '/' in it.\n")
|
634
628
|
print " Did you use a URL instead of just the domain?\n"
|
635
|
-
print "Examples: -d example.com -d '*.example.com' -d
|
629
|
+
print "Examples: -d example.com -d '*.example.com' -d another.site"
|
636
630
|
print
|
637
631
|
raise SystemExit(1)
|
638
632
|
|
@@ -640,7 +634,7 @@ def check_domains(domains):
|
|
640
634
|
if all(map(lambda c: c.isdigit() or c == '.', dom)):
|
641
635
|
sys.stderr.write("Error: Domain must be a hostname not an IP\n")
|
642
636
|
print
|
643
|
-
print "Examples: -d example.com -d '*.example.com' -d
|
637
|
+
print "Examples: -d example.com -d '*.example.com' -d another.site"
|
644
638
|
print
|
645
639
|
raise SystemExit(1)
|
646
640
|
|
@@ -650,7 +644,16 @@ def check_domains(domains):
|
|
650
644
|
sys.stderr.write(
|
651
645
|
"Error: Domain requires a TLD of 2 characters or more\n")
|
652
646
|
print
|
653
|
-
print "Example: -d example.tld -d '*.example.tld' -d
|
647
|
+
print "Example: -d example.tld -d '*.example.tld' -d another.tld"
|
648
|
+
print
|
649
|
+
raise SystemExit(1)
|
650
|
+
|
651
|
+
# *.com will break uploading to S3
|
652
|
+
if dom == "*.com":
|
653
|
+
sys.stderr.write(
|
654
|
+
"Error: Matching *.com will break videos and logs. Use a hostname.\n")
|
655
|
+
print
|
656
|
+
print "Example: -d example.com -d *.example.com"
|
654
657
|
print
|
655
658
|
raise SystemExit(1)
|
656
659
|
|
@@ -709,16 +712,20 @@ Performance tip:
|
|
709
712
|
og.add_option("--readyfile",
|
710
713
|
help="Path of the file to drop when the tunnel is ready "
|
711
714
|
"for tests to run. By default, no file is dropped.")
|
715
|
+
og.add_option("--use-ssh-config", action="store_true", default=False,
|
716
|
+
help="Use the local SSH config. WARNING: Turning this on "
|
717
|
+
"may break the script!")
|
718
|
+
og.add_option("--rest-url", default="https://saucelabs.com/rest",
|
719
|
+
help=optparse.SUPPRESS_HELP)
|
720
|
+
og.add_option("--allow-unclean-exit", action="store_true", default=False,
|
721
|
+
help=optparse.SUPPRESS_HELP)
|
712
722
|
op.add_option_group(og)
|
713
723
|
|
714
724
|
og = optparse.OptionGroup(op, "Script debugging options")
|
715
|
-
og.add_option("--
|
716
|
-
help="
|
717
|
-
og.add_option("--debug-ssh", action="store_true", default=False)
|
725
|
+
og.add_option("--debug-ssh", action="store_true", default=False,
|
726
|
+
help="Log SSH output.")
|
718
727
|
og.add_option("--latency-log", type=int, default=LATENCY_LOG,
|
719
|
-
help="Threshold
|
720
|
-
"logged. [%default]")
|
721
|
-
og.add_option("--allow-unclean-exit", action="store_true", default=False)
|
728
|
+
help="Threshold for logging latency (ms) [%default]")
|
722
729
|
op.add_option_group(og)
|
723
730
|
|
724
731
|
(options, args) = op.parse_args()
|
@@ -872,8 +879,10 @@ def run(options, dependency_versions=None):
|
|
872
879
|
logger.info("** Please contact help@saucelabs.com")
|
873
880
|
peace_out(tunnel, returncode=1) # exits
|
874
881
|
|
875
|
-
ssh = ReverseSSH(tunnel, options.host,
|
876
|
-
options.
|
882
|
+
ssh = ReverseSSH(tunnel=tunnel, host=options.host,
|
883
|
+
ports=options.ports, tunnel_ports=options.tunnel_ports,
|
884
|
+
use_ssh_config=options.use_ssh_config,
|
885
|
+
debug=options.debug_ssh)
|
877
886
|
try:
|
878
887
|
ssh.run(options.readyfile)
|
879
888
|
except (ReverseSSHError, TunnelMachineError), e:
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sauce
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 41
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 12
|
9
|
-
-
|
10
|
-
version: 0.12.
|
9
|
+
- 3
|
10
|
+
version: 0.12.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Sean Grove
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-12-
|
19
|
+
date: 2010-12-16 00:00:00 -08:00
|
20
20
|
default_executable: sauce
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|