Add interactive mode
This commit is contained in:
parent
aa17fe4e00
commit
bbdda36e4c
@ -1,17 +1,21 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
require "base64"
|
require "base64"
|
||||||
|
require "io/console"
|
||||||
require "optparse"
|
require "optparse"
|
||||||
require "socket"
|
require "socket"
|
||||||
|
|
||||||
usage_output = "USAGE:\n github-fast-env SCRIPT_PATH [options]"
|
usage_output = "USAGE:\n github-fast-env SCRIPT_PATH [options]"
|
||||||
|
|
||||||
$options = {:verbose => false}
|
$options = {:verbose => false, :interactive => false}
|
||||||
OptionParser.new do |options|
|
OptionParser.new do |options|
|
||||||
options.banner = usage_output
|
options.banner = usage_output
|
||||||
options.on("-v", "--verbose", "Show verbose output") do
|
options.on("-v", "--verbose", "Show verbose output") do
|
||||||
$options[:verbose] = true
|
$options[:verbose] = true
|
||||||
end
|
end
|
||||||
|
options.on("-i", "--interactive", "Run an interactive session using a pseudoterminal") do
|
||||||
|
$options[:interactive] = true
|
||||||
|
end
|
||||||
end.parse!
|
end.parse!
|
||||||
|
|
||||||
if not ARGV or ARGV.empty?
|
if not ARGV or ARGV.empty?
|
||||||
@ -34,9 +38,13 @@ control_socket_path = "/tmp/github-fast-envd.sock"
|
|||||||
|
|
||||||
$control_socket = UNIXSocket.new(control_socket_path)
|
$control_socket = UNIXSocket.new(control_socket_path)
|
||||||
|
|
||||||
|
$original_stdin = $stdin.dup
|
||||||
|
$original_stdout = $stdout.dup
|
||||||
|
$origianl_stderr = $stderr.dup
|
||||||
|
|
||||||
def log(level, message)
|
def log(level, message)
|
||||||
if level == "error" or $options[:verbose]
|
if level == "error" or $options[:verbose]
|
||||||
$stderr.puts "[github-fast-env] #{level}: #{message}"
|
$origianl_stderr.puts "[github-fast-env] #{level}: #{message}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -89,7 +97,12 @@ end
|
|||||||
log "info", "connected to control socket"
|
log "info", "connected to control socket"
|
||||||
|
|
||||||
encoded_script_path = Base64.encode64(script_path).delete("\n")
|
encoded_script_path = Base64.encode64(script_path).delete("\n")
|
||||||
$control_socket.puts "new v1 named-pipes #{encoded_script_path}"
|
|
||||||
|
if $options[:interactive]
|
||||||
|
$control_socket.puts "new v1 pseudoterminal #{encoded_script_path}"
|
||||||
|
else
|
||||||
|
$control_socket.puts "new v1 named-pipes #{encoded_script_path}"
|
||||||
|
end
|
||||||
|
|
||||||
pipes = {"stdin" => nil, "stdout" => nil, "stderr" => nil}
|
pipes = {"stdin" => nil, "stdout" => nil, "stderr" => nil}
|
||||||
|
|
||||||
@ -115,10 +128,27 @@ while true
|
|||||||
pipes["stderr"] = File::open("#{pipe_base_path}.stderr", "r")
|
pipes["stderr"] = File::open("#{pipe_base_path}.stderr", "r")
|
||||||
pipes["stderr"].sync = true
|
pipes["stderr"].sync = true
|
||||||
|
|
||||||
|
read_ios = [$control_socket, $stdin, pipes["stdout"], pipes["stderr"]]
|
||||||
|
|
||||||
log "info", "connected via named pipes"
|
log "info", "connected via named pipes"
|
||||||
elsif command == "pseudoterminal"
|
elsif command == "pseudoterminal"
|
||||||
log "error", "not yet implemented"
|
if arguments.empty?
|
||||||
exit 1
|
log "error", "malformed response"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
pseudoterminal_path = Base64.decode64(arguments[0])
|
||||||
|
|
||||||
|
log "info", "connecting to pseudoterminal at #{pseudoterminal_path}"
|
||||||
|
|
||||||
|
pseudoterminal_io = File::open(pseudoterminal_path, File::RDWR | File::NOCTTY)
|
||||||
|
|
||||||
|
pipes["stdin"] = pseudoterminal_io
|
||||||
|
pipes["stdout"] = pseudoterminal_io
|
||||||
|
|
||||||
|
read_ios = [$control_socket, $stdin, pipes["stdout"]]
|
||||||
|
|
||||||
|
log "info", "connected via pseudoterminal"
|
||||||
else
|
else
|
||||||
log "error", "malformed response"
|
log "error", "malformed response"
|
||||||
exit 1
|
exit 1
|
||||||
@ -128,8 +158,6 @@ end
|
|||||||
log "info", "ready"
|
log "info", "ready"
|
||||||
$control_socket.puts "ready"
|
$control_socket.puts "ready"
|
||||||
|
|
||||||
read_ios = [$control_socket, $stdin, pipes["stdout"], pipes["stderr"]]
|
|
||||||
|
|
||||||
exit_code = "unknown"
|
exit_code = "unknown"
|
||||||
|
|
||||||
while read_ios.include?($control_socket) or read_ios.include?(pipes["stdout"]) or read_ios.include?(pipes["stderr"])
|
while read_ios.include?($control_socket) or read_ios.include?(pipes["stdout"]) or read_ios.include?(pipes["stderr"])
|
||||||
@ -165,7 +193,7 @@ while read_ios.include?($control_socket) or read_ios.include?(pipes["stdout"]) o
|
|||||||
log "warn", "received input from unknown stream"
|
log "warn", "received input from unknown stream"
|
||||||
end
|
end
|
||||||
rescue EOFError
|
rescue EOFError
|
||||||
log "trace", "closing stream"
|
log "trace", "closing stream #{ready_read_io}"
|
||||||
ready_read_io.close
|
ready_read_io.close
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env ruby
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
require "base64"
|
require "base64"
|
||||||
|
require "io/console"
|
||||||
require "socket"
|
require "socket"
|
||||||
|
|
||||||
#require "/data/github/current/config/environment"
|
#require "/data/github/current/config/environment"
|
||||||
@ -116,6 +117,35 @@ def set_up_named_pipes(control_socket, connection_id)
|
|||||||
$stderr.reopen(stderr)
|
$stderr.reopen(stderr)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_up_pseudoterminal(control_socket)
|
||||||
|
require "pty"
|
||||||
|
|
||||||
|
master, client = PTY.open
|
||||||
|
master.raw!
|
||||||
|
|
||||||
|
File.chmod 0600, client.path
|
||||||
|
|
||||||
|
client_path = Base64.encode64(client.path).delete("\n")
|
||||||
|
client.close
|
||||||
|
|
||||||
|
control_socket.puts "pseudoterminal #{client_path}"
|
||||||
|
|
||||||
|
$stderr.puts " set up pseudoterminal"
|
||||||
|
|
||||||
|
control_socket.puts "ready"
|
||||||
|
|
||||||
|
response = control_socket.readline.strip
|
||||||
|
|
||||||
|
if response != "ready"
|
||||||
|
raise ClientError.new "invalid command"
|
||||||
|
Kernel.exit!
|
||||||
|
end
|
||||||
|
|
||||||
|
$stdin.reopen(master)
|
||||||
|
$stdout.reopen(master)
|
||||||
|
$stderr.reopen(master)
|
||||||
|
end
|
||||||
|
|
||||||
while true
|
while true
|
||||||
control_socket = control_server.accept
|
control_socket = control_server.accept
|
||||||
$stderr.puts "- new connection"
|
$stderr.puts "- new connection"
|
||||||
@ -157,7 +187,7 @@ while true
|
|||||||
if mode == "named-pipes"
|
if mode == "named-pipes"
|
||||||
set_up_named_pipes(control_socket, connection_id)
|
set_up_named_pipes(control_socket, connection_id)
|
||||||
else
|
else
|
||||||
raise ClientError.new "not yet implemented"
|
set_up_pseudoterminal(control_socket)
|
||||||
end
|
end
|
||||||
|
|
||||||
original_stderr.puts " executing script " + script_path
|
original_stderr.puts " executing script " + script_path
|
||||||
|
Loading…
Reference in New Issue
Block a user