1#!/usr/bin/env python 2# 3# Usage: bootstrap_client.py <address>[:port] <command> ... 4# 5# <command> and the following arguments are concatenated (separated by a space) 6# and passed to a shell on the server. 7 8import os 9import select 10import socket 11import sys 12 13 14port = 4242 15bufferSize = 4 * 1024 16 17# interpret command line args 18if len(sys.argv) < 3: 19 sys.exit('Usage: ' + sys.argv[0] + ' <address>[:<port>] <command>') 20 21address = sys.argv[1] 22portIndex = address.find(':') 23if portIndex >= 0: 24 port = int(address[portIndex + 1:]) 25 address = address[:portIndex] 26 27commandToRun = " ".join(sys.argv[2:]) 28 29# create sockets and connect to server 30controlConnection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 31stdioConnection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 32stderrConnection = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 33 34try: 35 controlConnection.connect((address, port)) 36 stdioConnection.connect((address, port)) 37 stderrConnection.connect((address, port)) 38except socket.error, msg: 39 sys.exit('Failed to connect to %s port %d: %s' % (address, port, msg[1])) 40 41# send command length and command 42controlConnection.send("%08d" % len(commandToRun)) 43controlConnection.send(commandToRun) 44 45# I/O loop. We quit when all sockets have been closed. 46exitCode = '' 47connections = [controlConnection, stdioConnection, stderrConnection, sys.stdin] 48 49while connections and (len(connections) > 1 or not sys.stdin in connections): 50 (readable, writable, exceptions) = select.select(connections, [], 51 connections) 52 53 if sys.stdin in readable: 54 data = sys.stdin.readline(bufferSize) 55 if data: 56 stdioConnection.send(data) 57 else: 58 connections.remove(sys.stdin) 59 stdioConnection.shutdown(socket.SHUT_WR) 60 61 if stdioConnection in readable: 62 data = stdioConnection.recv(bufferSize) 63 if data: 64 sys.stdout.write(data) 65 else: 66 connections.remove(stdioConnection) 67 68 if stderrConnection in readable: 69 data = stderrConnection.recv(bufferSize) 70 if data: 71 sys.stderr.write(data) 72 else: 73 connections.remove(stderrConnection) 74 75 if controlConnection in readable: 76 data = controlConnection.recv(bufferSize) 77 if data: 78 exitCode += data 79 else: 80 connections.remove(controlConnection) 81 82# either an exit code has been sent or we consider this an error 83if exitCode: 84 sys.exit(int(exitCode)) 85sys.exit(1) 86