-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #27 from unifio/yl-wip2
0.5.0 (October 5, 2016)
- Loading branch information
Showing
16 changed files
with
308 additions
and
145 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,13 @@ | ||
- individual state-stores: would be nice if it had something to describe the backing input types | ||
- stack caching opportunities if they're called multiple times in the rake tasks | ||
- consider httparty vs rest-client | ||
- Use the invalid yaml syntax to figure out more things in rake tasks that needs to be lazy loaded | ||
- Like the idea of maybe splitting out the syntax elements to a different gem. Gem installation & management would become easier | ||
- missing spec around reports? | ||
- Look into muting the reporter as dev default: https://github.com/ci-reporter/ci_reporter | ||
- Look into getting HieraDB wrapper to read .yml files | ||
- Terraform: Nil vars should default to empty hash? | ||
- Terraform CLI in docker probably isn't going anywhere, might need to figure out a nicer way of handling this | ||
- Consider automatically feeding in env values into docker as -env-file | ||
- Use covalence to do verification on the open source stacks: | ||
- terraform-aws-openvpn | ||
- Plugin architecture | ||
- rollup tasks in terraform need to check terraform only tasks | ||
- stack_repository: backfill packer related tests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,122 @@ | ||
# A WIP, this will eventually wrap Open3#popen3 to provide better cli control | ||
# | ||
#require 'open3' | ||
require 'open3' | ||
require 'highline' | ||
|
||
require_relative '../../../covalence' | ||
|
||
module Covalence | ||
class PopenWrapper | ||
def self.run(cmds, path, args, dry_run: false) | ||
# TODO: terraform cmd env switch | ||
#cmd = "terraform #{[*cmds].join(' ')}" | ||
|
||
# TODO: implement path prefix for the docker runs, see @tf_cmd | ||
cmd_string = [*cmds] | ||
cmd_string += [*args] unless args.blank? | ||
cmd_string << path unless path.blank? | ||
|
||
#TODO debug command string maybe | ||
#TODO debug command args maybe | ||
|
||
# TODO: read through http://ruby-doc.org/stdlib-2.0.0/libdoc/tmpdir/rdoc/Dir.html to see how to make this optionally persist | ||
#stdout, stderr, status = Open3.capture3(ENV, "terraform", *cmd_string, chdir: tmp_dir) | ||
# TODO: cmd escape issues with -var. | ||
#stdout, stderr, status = Open3.capture3(ENV, cmd_string.join(' '), chdir: path) | ||
#if status != 0 | ||
#raise RuntimeError, "Command failed with status (#{status}): \n#{stderr}\n#{stdout}" | ||
#else | ||
#puts stdout | ||
#stdout.strip | ||
#end | ||
|
||
run_cmd = cmd_string.join(' ') | ||
Covalence::LOGGER.warn "---" | ||
Covalence::LOGGER.warn run_cmd | ||
|
||
Kernel.system(ENV.to_h, run_cmd) unless dry_run | ||
class << self | ||
|
||
def run(cmds, path, args, | ||
stdin_io: STDIN, | ||
stdout_io: STDOUT, | ||
stderr_io: STDERR, | ||
debug: Covalence::DEBUG_CLI, | ||
dry_run: false, | ||
ignore_exitcode: false) | ||
|
||
# TODO: implement path prefix for the docker runs, see @tf_cmd | ||
cmd_string = [*cmds] | ||
# TODO: cmd escape issues with -var. | ||
cmd_string += [*args] unless args.blank? | ||
cmd_string << path unless path.blank? | ||
|
||
#TODO debug command string maybe | ||
#TODO debug command args maybe | ||
|
||
run_cmd = cmd_string.join(' ') | ||
print_cmd_string(run_cmd) | ||
if dry_run | ||
run_cmd = Covalence::DRY_RUN_CMD | ||
end | ||
|
||
if debug | ||
return unless HighLine.new.agree('Execute? [y/n]') | ||
end | ||
|
||
spawn_subprocess(ENV, run_cmd, { | ||
stdin_io: stdin_io, | ||
stdout_io: stdout_io, | ||
stderr_io: stderr_io, | ||
ignore_exitcode: ignore_exitcode | ||
}) | ||
end | ||
|
||
private | ||
def print_cmd_string(cmd_string) | ||
Covalence::LOGGER.warn "---" | ||
Covalence::LOGGER.warn cmd_string | ||
end | ||
|
||
def spawn_subprocess(env, run_cmd, | ||
stdin_io: STDIN, | ||
stdout_io: STDOUT, | ||
stderr_io: STDERR, | ||
ignore_exitcode: false) | ||
Signal.trap("INT") {} #Disable parent process from exiting, orphaning the child fork below | ||
wait_thread = nil | ||
|
||
Open3.popen3(env, run_cmd) do |stdin, stdout, stderr, wait_thr| | ||
mappings = { stdin_io => stdin, stdout => stdout_io, stderr => stderr_io } | ||
wait_thread = wait_thr | ||
|
||
Signal.trap("INT") { | ||
Process.kill("INT", wait_thr.pid) | ||
Process.wait(wait_thr.pid, Process::WNOHANG) | ||
|
||
exit(wait_thr.value.exitstatus) | ||
} # let SIGINT drop into the child process | ||
|
||
handle_io_streams(mappings, stdin_io) | ||
end | ||
|
||
Signal.trap("INT") { exit } #Restore parent SIGINT | ||
|
||
return if ignore_exitcode | ||
exit(wait_thread.value.exitstatus) unless wait_thread.value.success? | ||
end | ||
|
||
def handle_io_streams(mappings, stdin_io) | ||
inputs = mappings.keys | ||
streams_ready_for_eof_check = [] | ||
|
||
until inputs.empty? || (inputs.size == 1 && inputs.first == stdin_io) do | ||
|
||
readable_inputs, _ = IO.select(inputs, [], []) | ||
streams_ready_for_eof_check = readable_inputs | ||
|
||
streams_ready_for_eof_check.select(&:eof).each do |src| | ||
Covalence::LOGGER.debug "Stopping redirection from an IO in EOF: " + src.inspect | ||
# `select`ing an IO which has reached EOF blocks forever. | ||
# So you have to delete such IO from the array of IOs to `select`. | ||
inputs.delete src | ||
|
||
# You must close the child process' STDIN immeditely after the parent's STDIN reached EOF, | ||
# or some kinds of child processes never exit. | ||
# e.g.) echo foobar | joumae run -- cat | ||
# After the `echo` finished outputting `foobar`, you have to tell `cat` about that or `cat` will wait for more inputs forever. | ||
mappings[src].close if src == stdin_io | ||
end | ||
|
||
break if inputs.empty? || (inputs.size == 1 && inputs.first == stdin_io) | ||
|
||
readable_inputs.each do |input| | ||
begin | ||
data = input.read_nonblock(1024) | ||
output = mappings[input] | ||
output.write(data) | ||
output.flush | ||
rescue EOFError => e | ||
Covalence::LOGGER.debug "Reached EOF: #{e}" | ||
inputs.delete input | ||
rescue Errno::EPIPE => e | ||
Covalence::LOGGER.debug "Handled error: #{e}: io: #{input.inspect}" | ||
inputs.delete input | ||
end | ||
end #readable_inputs | ||
end #until inputs.empty? | ||
end #handle_io_streams | ||
|
||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.