Permalink
Browse files

Merge branch '1.1.X'

  • Loading branch information...
brosner committed Aug 18, 2012
2 parents 25b52bd + fefdba5 commit 14f48f08570211a1c22360ae8e3d574bc56a8efa
Showing with 121 additions and 65 deletions.
  1. +6 −0 CHANGELOG.rst
  2. +1 −1 gondor/__init__.py
  3. +30 −64 gondor/__main__.py
  4. +64 −0 gondor/run.py
  5. +20 −0 gondor/utils.py
View
@@ -2,6 +2,12 @@
CHANGELOG
=========
+1.1.4
+=====
+
+ * added very basic and likely not working support for run on Windows
+ * added env section to gondor.yml
+
1.1.3
=====
View
@@ -1 +1 @@
-__version__ = "1.1.3"
+__version__ = "1.1.4"
View
@@ -1,11 +1,9 @@
import argparse
import ConfigParser
-import errno
import gzip
import itertools
import os
import re
-import select
import socket
import ssl
import subprocess
@@ -29,13 +27,8 @@
from gondor import http, utils
from gondor.api import make_api_call
from gondor.progressbar import ProgressBar
-
-
-out = utils.out
-err = utils.err
-error = utils.error
-warn = utils.warn
-api_error = utils.api_error
+from gondor.run import unix_run_poll, win32_run_poll
+from gondor.utils import out, err, error, warn, api_error
DEFAULT_ENDPOINT = "https://api.gondor.io"
@@ -479,6 +472,8 @@ def cmd_run(args, env, config):
"command": " ".join(command),
"app": json.dumps(config["app"]),
}
+ if sys.platform == "win32":
+ params["term"] = "win32"
try:
params.update({
"tc": utils.check_output(["tput", "cols"]).strip(),
@@ -532,62 +527,32 @@ def cmd_run(args, env, config):
if args.detached:
err("Check your logs for output.\n")
else:
- def run_set_buffer(value):
- cmd = ["stty", "-icanon", "-echo"] if value else ["stty", "icanon", "echo"]
- if sys.stdin.isatty():
- try:
- subprocess.check_call(cmd)
- except (OSError, subprocess.CalledProcessError):
- if args.verbose > 1:
- out("Unable to run stty; using dumb terminal")
- run_set_buffer(True)
- try:
- # connect to process
- for x in xrange(5):
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- ssl_kwargs = {
- "ca_certs": os.path.join(os.path.abspath(os.path.dirname(__file__)), "ssl", "run.gondor.io.crt"),
- "cert_reqs": ssl.CERT_REQUIRED,
- "ssl_version": ssl.PROTOCOL_SSLv3
- }
- sock = ssl.wrap_socket(sock, **ssl_kwargs)
- try:
- sock.connect(endpoint)
- except IOError, e:
- time.sleep(0.5)
- continue
- else:
- err("[ok]\n")
- if args.verbose > 1:
- err("Terminal set to %sx%s\n" % (tc, tl))
- break
+ # connect to process
+ for x in xrange(5):
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ ssl_kwargs = {
+ "ca_certs": os.path.join(os.path.abspath(os.path.dirname(__file__)), "ssl", "run.gondor.io.crt"),
+ "cert_reqs": ssl.CERT_REQUIRED,
+ "ssl_version": ssl.PROTOCOL_SSLv3
+ }
+ sock = ssl.wrap_socket(sock, **ssl_kwargs)
+ try:
+ sock.connect(endpoint)
+ except IOError, e:
+ time.sleep(0.5)
+ continue
else:
- err("[failed]\n")
- error("unable to attach to process (reason: %s)\n" % e)
- while True:
- try:
- try:
- rr, rw, er = select.select([sock, sys.stdin], [], [], 0.1)
- except select.error, e:
- if e.args[0] == errno.EINTR:
- continue
- raise
- if sock in rr:
- data = sock.recv(4096)
- if not data:
- break
- while data:
- n = os.write(sys.stdout.fileno(), data)
- data = data[n:]
- if sys.stdin in rr:
- data = os.read(sys.stdin.fileno(), 4096)
- while data:
- n = sock.send(data)
- data = data[n:]
- except KeyboardInterrupt:
- sock.sendall(chr(3))
- finally:
- run_set_buffer(False)
+ err("[ok]\n")
+ if args.verbose > 1:
+ err("Terminal set to %sx%s\n" % (tc, tl))
+ break
+ else:
+ err("[failed]\n")
+ error("unable to attach to process (reason: %s)\n" % e)
+ if sys.platform == "win32":
+ win32_run_poll(sock)
+ else:
+ unix_run_poll(sock)
def cmd_delete(args, env, config):
@@ -980,6 +945,7 @@ def main():
"settings_module": local_config.get("django", {}).get("settings_module"),
"managepy": local_config.get("django", {}).get("managepy"),
"local_settings": local_config.get("django", {}).get("local_settings"),
+ "env": local_config.get("env", {}),
}
})
View
@@ -0,0 +1,64 @@
+import errno
+import os
+import select
+import sys
+
+from gondor.utils import stdin_buffer, confirm
+
+
+def unix_run_poll(sock):
+ with stdin_buffer() as stdin:
+ while True:
+ try:
+ try:
+ rr, rw, er = select.select([sock, sys.stdin], [], [], 0.1)
+ except select.error, e:
+ if e.args[0] == errno.EINTR:
+ continue
+ raise
+ if sock in rr:
+ data = sock.recv(4096)
+ if not data:
+ break
+ while data:
+ n = os.write(sys.stdout.fileno(), data)
+ data = data[n:]
+ if sys.stdin in rr:
+ data = os.read(sys.stdin.fileno(), 4096)
+ while data:
+ n = sock.send(data)
+ data = data[n:]
+ except KeyboardInterrupt:
+ sock.sendall(chr(3))
+
+
+def win32_run_poll(sock):
+ sys.stderr.write("WARNING: Windows support for this command is broken.\n")
+ if not confirm("Would you like to run it anyways?"):
+ sys.exit(0)
+ import win32api, win32console, win32event, win32file
+ sock_event = win32event.CreateEvent(None, True, False, None)
+ win32file.WSAEventSelect(sock.fileno(), sock_event, win32file.FD_CLOSE | win32file.FD_READ)
+ stdin = win32api.GetStdHandle(win32api.STD_INPUT_HANDLE)
+ console = win32console.GetStdHandle(win32api.STD_INPUT_HANDLE)
+ handles = [stdin, sock_event]
+ try:
+ while True:
+ i = win32event.WaitForMultipleObjects(handles, 0, 1000)
+ if i == win32event.WAIT_TIMEOUT:
+ continue
+ if handles[i] == stdin:
+ rs = console.ReadConsoleInput(1)
+ if rs[0].EventType == win32console.KEY_EVENT and rs[0].KeyDown:
+ c = rs[0].Char
+ if c == "\x00":
+ continue
+ sock.send(c)
+ if handles[i] == sock_event:
+ data = sock.recv(4096)
+ if not data:
+ break
+ sys.stdout.write(data)
+ win32event.ResetEvent(sock_event)
+ finally:
+ win32api.CloseHandle(sock_event)
View
@@ -1,3 +1,4 @@
+import contextlib
import os
import subprocess
import sys
@@ -47,6 +48,11 @@ def warn(msg):
err("WARNING: %s" % msg)
+def confirm(msg):
+ answer = raw_input("%s [y/n]: ")
+ return answer == "y"
+
+
def api_error(e):
data = e.read()
try:
@@ -121,3 +127,17 @@ def check_output(*popenargs, **kwargs):
cmd = popenargs[0]
raise subprocess.CalledProcessError(retcode, cmd, output=output)
return output
+
+
+@contextlib.contextmanager
+def stdin_buffer():
+ import termios, tty
+ if sys.stdin.isatty():
+ before = termios.tcgetattr(sys.stdin)
+ tty.setcbreak(sys.stdin.fileno())
+ try:
+ yield
+ finally:
+ termios.tcsetattr(sys.stdin, termios.TCSADRAIN, before)
+ else:
+ yield

0 comments on commit 14f48f0

Please sign in to comment.