sauce 0.12.2 → 0.12.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/VERSION +1 -1
  2. data/support/sauce_connect +39 -30
  3. metadata +4 -4
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.12.2
1
+ 0.12.3
@@ -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 = 20
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, debug=False):
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
- ssh_known_hosts = os.path.join(os.environ['HOME'], ".ssh", "known_hosts")
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-keygen %s -R %s;%s;"
407
- % (verbosity, self.tunnel.host, wait) +
408
- "spawn ssh-keygen %s -R %s;%s;" % (verbosity, host_ip, wait) +
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("--- fin ---")
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 cdn.example.org"
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 cdn.example.org"
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 cdn.example.tld"
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("--rest-url", default="https://saucelabs.com/rest",
716
- help="[%default]")
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 above which latency (ms) will be "
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, options.ports, options.tunnel_ports,
876
- options.debug_ssh)
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: 43
4
+ hash: 41
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 12
9
- - 2
10
- version: 0.12.2
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-15 00:00:00 -08:00
19
+ date: 2010-12-16 00:00:00 -08:00
20
20
  default_executable: sauce
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency