summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilip Hands <phil@hands.com>2017-03-03 13:34:45 +0100
committerPhilip Hands <phil@hands.com>2017-03-07 23:50:21 +0100
commitfaa4c759b90a365e532321f18979812f9b6442eb (patch)
tree4007f217eade8c6280ed5d5213906d160d1f0156
parent48327348c7ee0cceb1e8b5ddb082805651ee0fe0 (diff)
downloadjenkins.debian.net-faa4c759b90a365e532321f18979812f9b6442eb.tar.xz
lvc: reinstate VMcommand's ability to run commands and get results
This modifies the inittab to run a very simple loop on d-i's ttyS0 that reads commands from stdin, runs them and tops and tails the output with various control characters to make it easier to see when we have a result. It outputs a BEL (Ctrl-G, \a, \007) at the start, then an STX (\002) before running the command, and an ETX (\003) afterwards, to bracket STDOUT. After the ETX comes the command's return code, in decimal, then a US (\037), then comes the STDERR, and finally a NUL (\000) That lets us send an 'exit' and look for a BEL then issue a command and find the values required to populate the @returncode, @stdout and @stderr values.
-rw-r--r--cucumber/features/step_definitions/common_steps.rb14
-rw-r--r--cucumber/features/support/helpers/exec_helper.rb45
2 files changed, 41 insertions, 18 deletions
diff --git a/cucumber/features/step_definitions/common_steps.rb b/cucumber/features/step_definitions/common_steps.rb
index 328c5661..6f47bb93 100644
--- a/cucumber/features/step_definitions/common_steps.rb
+++ b/cucumber/features/step_definitions/common_steps.rb
@@ -208,6 +208,11 @@ When /^I start the computer$/ do
post_vm_start_hook
end
+When /^I execute "([^"]*)"$/ do |cmd|
+ info_log($vm.execute(cmd))
+end
+
+
Given /^I start Tails( from DVD)?( with network unplugged)?( and I login)?$/ do |dvd_boot, network_unplugged, do_login|
step "the computer is set to boot from the Tails DVD" if dvd_boot
if network_unplugged.nil?
@@ -289,7 +294,14 @@ Given /^I select the install mode$/ do
@screen.type(Sikuli::Key.TAB)
@boot_options = "" if @boot_options.nil?
- @screen.type(' preseed/early_command="echo DPMS=-s\\\\ 0 > /lib/debian-installer.d/S61Xnoblank ; sed -i /XF86_Switch_VT_/s/F/XF86_Switch_VT_/ /usr/share/X11/xkb/symbols/srvr_ctrl ; echo ttyS0::askfirst:-/bin/sh>>/etc/inittab;kill -HUP 1" blacklist=psmouse ' + @boot_options +
+ initcmd = 'printf \\\\\\\\07; while read x; do printf \\\\\\\\02; eval $x 2>/tmp/.remcmd_stderr; printf \\\\\\\\03%%s\\\\\\\\037 $?; cat /tmp/.remcmd_stderr; printf \\\\\\\\00; done'.gsub(/([$\\;>])/, '\\\\\0')
+ inittab_line = ('ttyS0::respawn:-/bin/sh -c \\\\047' + initcmd + '\\\\047').gsub(/ /, '\\ ')
+ @screen.type( ' preseed/early_command="echo DPMS=-s\\\\ 0 > /lib/debian-installer.d/S61Xnoblank;' +
+ ' sed -i /XF86_Switch_VT_/s/F/XF86_Switch_VT_/ /usr/share/X11/xkb/symbols/srvr_ctrl;' +
+ ' set -x;' +
+ ' { printf ' + inittab_line + ';echo;}>>/etc/inittab;' +
+ ' kill -HUP 1" blacklist=psmouse ' +
+ @boot_options +
Sikuli::Key.ENTER)
debug_log("debug: wait for the remote shell to respond...", :color => :blue)
$vm.wait_until_remote_shell_is_up
diff --git a/cucumber/features/support/helpers/exec_helper.rb b/cucumber/features/support/helpers/exec_helper.rb
index 8be1e5c4..70d22d37 100644
--- a/cucumber/features/support/helpers/exec_helper.rb
+++ b/cucumber/features/support/helpers/exec_helper.rb
@@ -13,9 +13,8 @@ class VMCommand
def VMCommand.wait_until_remote_shell_is_up(vm, timeout = 180)
try_for(timeout, :msg => "Remote shell seems to be down") do
- sleep(20)
- Timeout::timeout(10) do
- VMCommand.execute(vm, "echo 'true'")
+ Timeout::timeout(20) do
+ VMCommand.execute(vm, "echo 'hello?'")
end
end
end
@@ -36,26 +35,38 @@ class VMCommand
socket = TCPSocket.new("127.0.0.1", vm.get_remote_shell_port)
debug_log("#{type}ing as #{options[:user]}: #{cmd}")
begin
- #socket.puts(JSON.dump([type, options[:user], cmd]))
- socket.puts( "\n")
- sleep(1)
- socket.puts( "\003")
- sleep(1)
- socket.puts( cmd + "\n")
- sleep(1)
+ sleep 0.5
+ while socket.ready?
+ s = socket.recv(1024)
+ debug_log("#{type} pre-exit-debris: #{s}") if not(options[:spawn])
+ end
+ socket.puts( "\nexit\n")
+ sleep 1
+ s = socket.readline(sep = "\007")
+ debug_log("#{type} post-exit-read: #{s}") if not(options[:spawn])
while socket.ready?
- s = socket.readline(sep = "\n").chomp("\n")
- debug_log("#{type} read: #{s}") if not(options[:spawn])
- if ('true' == s) then
- break
- end
+ s = socket.recv(1024)
+ debug_log("#{type} post-exit-debris: #{s}") if not(options[:spawn])
end
+ socket.puts( cmd + "\n")
+ s = socket.readline(sep = "\000")
+ debug_log("#{type} post-cmd-read: #{s}") if not(options[:spawn])
+ s.chomp!("\000")
ensure
+ debug_log("closing the remote-command socket") if not(options[:spawn])
socket.close
end
- if ('true' == s)
- return true
+ (s, s_err, x) = s.split("\037")
+ s_err = "" if s_err.nil?
+ (s, s_retcode, y) = s.split("\003")
+ (s, s_out, z) = s.split("\002")
+ s_out = "" if s_out.nil?
+
+ if (s_retcode.to_i.to_s == s_retcode.to_s && x.nil? && y.nil? && z.nil?) then
+ debug_log("returning [returncode=`#{s_retcode.to_i}`,\n\toutput=`#{s_out}`,\n\tstderr=`#{s_err}`]\nwhile discarding `#{s}`.") if not(options[:spawn])
+ return [s_retcode.to_i, s_out, s_err]
else
+ debug_log("failed to parse results, retrying\n")
return VMCommand.execute(vm, cmd, options)
end
end