rework how buildozer-remote pipeline commands works (support stdin now.)
This commit is contained in:
parent
17cc24ea87
commit
057f3bcb59
1 changed files with 99 additions and 17 deletions
|
@ -12,14 +12,15 @@ Layout directory for buildozer:
|
||||||
|
|
||||||
__version__ = '0.3-dev'
|
__version__ = '0.3-dev'
|
||||||
|
|
||||||
import shelve
|
|
||||||
import zipfile
|
|
||||||
import sys
|
|
||||||
import fcntl
|
import fcntl
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import shelve
|
||||||
|
import socket
|
||||||
|
import sys
|
||||||
|
import zipfile
|
||||||
from select import select
|
from select import select
|
||||||
from sys import stdout, stderr, exit
|
from sys import stdout, stderr, stdin, exit
|
||||||
from urllib import urlretrieve
|
from urllib import urlretrieve
|
||||||
from re import search
|
from re import search
|
||||||
from ConfigParser import SafeConfigParser
|
from ConfigParser import SafeConfigParser
|
||||||
|
@ -29,6 +30,14 @@ from os import environ, unlink, rename, walk, sep, listdir, makedirs
|
||||||
from copy import copy
|
from copy import copy
|
||||||
from shutil import copyfile, rmtree, copytree
|
from shutil import copyfile, rmtree, copytree
|
||||||
|
|
||||||
|
# windows does not have termios...
|
||||||
|
try:
|
||||||
|
import termios
|
||||||
|
import tty
|
||||||
|
has_termios = True
|
||||||
|
except ImportError:
|
||||||
|
has_termios = False
|
||||||
|
|
||||||
RESET_SEQ = "\033[0m"
|
RESET_SEQ = "\033[0m"
|
||||||
COLOR_SEQ = "\033[1;{0}m"
|
COLOR_SEQ = "\033[1;{0}m"
|
||||||
BOLD_SEQ = "\033[1m"
|
BOLD_SEQ = "\033[1m"
|
||||||
|
@ -196,8 +205,16 @@ class Buildozer(object):
|
||||||
show_output = kwargs.pop('show_output')
|
show_output = kwargs.pop('show_output')
|
||||||
get_stdout = kwargs.pop('get_stdout', False)
|
get_stdout = kwargs.pop('get_stdout', False)
|
||||||
get_stderr = kwargs.pop('get_stderr', False)
|
get_stderr = kwargs.pop('get_stderr', False)
|
||||||
|
break_on_error = kwargs.pop('break_on_error', True)
|
||||||
|
sensible = kwargs.pop('sensible', False)
|
||||||
|
|
||||||
|
if not sensible:
|
||||||
self.debug('Run {0!r}'.format(command))
|
self.debug('Run {0!r}'.format(command))
|
||||||
|
else:
|
||||||
|
if type(command) in (list, tuple):
|
||||||
|
self.debug('Run {0!r} ...'.format(command[0]))
|
||||||
|
else:
|
||||||
|
self.debug('Run {0!r} ...'.format(command.split()[0]))
|
||||||
self.debug('Cwd {}'.format(kwargs.get('cwd')))
|
self.debug('Cwd {}'.format(kwargs.get('cwd')))
|
||||||
|
|
||||||
# open the process
|
# open the process
|
||||||
|
@ -238,14 +255,14 @@ class Buildozer(object):
|
||||||
stderr.flush()
|
stderr.flush()
|
||||||
|
|
||||||
process.communicate()
|
process.communicate()
|
||||||
if process.returncode != 0:
|
if process.returncode != 0 and break_on_error:
|
||||||
self.error('Command failed: {0}'.format(command))
|
self.error('Command failed: {0}'.format(command))
|
||||||
raise BuildozerCommandException()
|
raise BuildozerCommandException()
|
||||||
if ret_stdout:
|
if ret_stdout:
|
||||||
ret_stdout = ''.join(ret_stdout)
|
ret_stdout = ''.join(ret_stdout)
|
||||||
if ret_stderr:
|
if ret_stderr:
|
||||||
ret_stderr = ''.join(ret_stderr)
|
ret_stderr = ''.join(ret_stderr)
|
||||||
return (ret_stdout, ret_stderr)
|
return (ret_stdout, ret_stderr, process.returncode)
|
||||||
|
|
||||||
def check_configuration_tokens(self):
|
def check_configuration_tokens(self):
|
||||||
'''Ensure the spec file is 'correct'.
|
'''Ensure the spec file is 'correct'.
|
||||||
|
@ -493,6 +510,8 @@ class Buildozer(object):
|
||||||
exclude_exts = self.config.getlist('app', 'source.exclude_exts', '')
|
exclude_exts = self.config.getlist('app', 'source.exclude_exts', '')
|
||||||
app_dir = self.app_dir
|
app_dir = self.app_dir
|
||||||
|
|
||||||
|
self.debug('Copy application source from {}'.format(source_dir))
|
||||||
|
|
||||||
rmtree(self.app_dir)
|
rmtree(self.app_dir)
|
||||||
|
|
||||||
for root, dirs, files in walk(source_dir):
|
for root, dirs, files in walk(source_dir):
|
||||||
|
@ -896,21 +915,84 @@ class BuildozerRemote(Buildozer):
|
||||||
|
|
||||||
def _ssh_command(self, command):
|
def _ssh_command(self, command):
|
||||||
self.debug('Execute remote command {}'.format(command))
|
self.debug('Execute remote command {}'.format(command))
|
||||||
rstdin, rstdout, rstderr = self._ssh_client.exec_command(command)
|
#shell = self._ssh_client.invoke_shell()
|
||||||
|
#shell.sendall(command)
|
||||||
# prepare fds
|
#shell.sendall('\nexit\n')
|
||||||
while True:
|
transport = self._ssh_client.get_transport()
|
||||||
chunk = rstdout.read(1)
|
channel = transport.open_session()
|
||||||
if chunk == '':
|
try:
|
||||||
break
|
channel.exec_command(command)
|
||||||
stdout.write(chunk)
|
self._interactive_shell(channel)
|
||||||
stdout.flush()
|
finally:
|
||||||
|
channel.close()
|
||||||
|
|
||||||
def usage(self):
|
def usage(self):
|
||||||
print 'Usage: buildozer-remote [--verbose] [remote-name] [buildozer args]'
|
print 'Usage: buildozer-remote [--verbose] [remote-name] [buildozer args]'
|
||||||
|
|
||||||
|
|
||||||
|
def _interactive_shell(self, chan):
|
||||||
|
if has_termios:
|
||||||
|
self._posix_shell(chan)
|
||||||
|
else:
|
||||||
|
self._windows_shell(chan)
|
||||||
|
|
||||||
|
def _posix_shell(self, chan):
|
||||||
|
oldtty = termios.tcgetattr(stdin)
|
||||||
|
try:
|
||||||
|
#tty.setraw(stdin.fileno())
|
||||||
|
#tty.setcbreak(stdin.fileno())
|
||||||
|
chan.settimeout(0.0)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
r, w, e = select([chan, stdin], [], [])
|
||||||
|
if chan in r:
|
||||||
|
try:
|
||||||
|
x = chan.recv(128)
|
||||||
|
if len(x) == 0:
|
||||||
|
print '\r\n*** EOF\r\n',
|
||||||
|
break
|
||||||
|
stdout.write(x)
|
||||||
|
stdout.flush()
|
||||||
|
#print len(x), repr(x)
|
||||||
|
except socket.timeout:
|
||||||
|
pass
|
||||||
|
if stdin in r:
|
||||||
|
x = stdin.read(1)
|
||||||
|
if len(x) == 0:
|
||||||
|
break
|
||||||
|
chan.sendall(x)
|
||||||
|
finally:
|
||||||
|
termios.tcsetattr(stdin, termios.TCSADRAIN, oldtty)
|
||||||
|
|
||||||
|
# thanks to Mike Looijmans for this code
|
||||||
|
def _windows_shell(self,chan):
|
||||||
|
import threading
|
||||||
|
|
||||||
|
stdout.write("Line-buffered terminal emulation. Press F6 or ^Z to send EOF.\r\n\r\n")
|
||||||
|
|
||||||
|
def writeall(sock):
|
||||||
|
while True:
|
||||||
|
data = sock.recv(256)
|
||||||
|
if not data:
|
||||||
|
stdout.write('\r\n*** EOF ***\r\n\r\n')
|
||||||
|
stdout.flush()
|
||||||
|
break
|
||||||
|
stdout.write(data)
|
||||||
|
stdout.flush()
|
||||||
|
|
||||||
|
writer = threading.Thread(target=writeall, args=(chan,))
|
||||||
|
writer.start()
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
d = stdin.read(1)
|
||||||
|
if not d:
|
||||||
|
break
|
||||||
|
chan.send(d)
|
||||||
|
except EOFError:
|
||||||
|
# user hit ^Z or F6
|
||||||
|
pass
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
try:
|
try:
|
||||||
Buildozer().run_command(sys.argv[1:])
|
Buildozer().run_command(sys.argv[1:])
|
||||||
|
|
Loading…
Reference in a new issue