lib/linux_admin/common.rb in linux_admin-0.7.0 vs lib/linux_admin/common.rb in linux_admin-0.8.0
- old
+ new
@@ -1,111 +1,17 @@
-require 'shellwords'
+require 'awesome_spawn'
class LinuxAdmin
module Common
def cmd(cmd)
Distro.local.class::COMMANDS[cmd]
end
def run(cmd, options = {})
- params = options[:params] || options[:parameters]
-
- launch_params = {}
- launch_params[:chdir] = options[:chdir] if options[:chdir]
-
- output = ""
- error = ""
- status = nil
- command_line = build_cmd(cmd, params)
-
- begin
- output, error = launch(command_line, launch_params)
- status = exitstatus
- ensure
- output ||= ""
- error ||= ""
- self.exitstatus = nil
- end
- rescue Errno::ENOENT => err
- raise NoSuchFileError.new(err.message) if NoSuchFileError.detected?(err.message)
- raise
- else
- CommandResult.new(command_line, output, error, status)
+ AwesomeSpawn.run(cmd, options)
end
def run!(cmd, options = {})
- params = options[:params] || options[:parameters]
- command_result = run(cmd, options)
-
- if command_result.exit_status != 0
- message = "#{cmd} exit code: #{command_result.exit_status}"
- raise CommandResultError.new(message, command_result)
- end
-
- command_result
- end
-
- private
-
- def sanitize(params)
- return [] if params.blank?
- params.collect do |k, v|
- v = case v
- when Array; v.collect {|i| i.to_s.shellescape}
- when NilClass; v
- else v.to_s.shellescape
- end
- [k, v]
- end
- end
-
- def assemble_params(sanitized_params)
- sanitized_params.collect do |pair|
- pair_joiner = pair.first.to_s.end_with?("=") ? "" : " "
- pair.flatten.compact.join(pair_joiner)
- end.join(" ")
- end
-
- def build_cmd(cmd, params = nil)
- return cmd.to_s if params.blank?
- "#{cmd} #{assemble_params(sanitize(params))}"
- end
-
- # IO pipes have a maximum size of 64k before blocking,
- # so we need to read and write synchronously.
- # http://stackoverflow.com/questions/13829830/ruby-process-spawn-stdout-pipe-buffer-size-limit/13846146#13846146
- THREAD_SYNC_KEY = "LinuxAdmin-exitstatus"
-
- def launch(cmd, spawn_options = {})
- out_r, out_w = IO.pipe
- err_r, err_w = IO.pipe
- pid = Kernel.spawn(cmd, {:err => err_w, :out => out_w}.merge(spawn_options))
- wait_for_process(pid, out_w, err_w)
- wait_for_pipes(out_r, err_r)
- end
-
- def wait_for_process(pid, out_w, err_w)
- self.exitstatus = :not_done
- Thread.new(Thread.current) do |parent_thread|
- _, status = Process.wait2(pid)
- out_w.close
- err_w.close
- parent_thread[THREAD_SYNC_KEY] = status.exitstatus
- end
- end
-
- def wait_for_pipes(out_r, err_r)
- out = out_r.read
- err = err_r.read
- sleep(0.1) while exitstatus == :not_done
- return out, err
- end
-
- def exitstatus
- Thread.current[THREAD_SYNC_KEY]
- end
-
- def exitstatus=(value)
- Thread.current[THREAD_SYNC_KEY] = value
+ AwesomeSpawn.run!(cmd, options)
end
end
end