PageRenderTime 28ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/hawk-0.4.1/hawk/lib/util.rb

https://github.com/dizopsin/deb-hawk
Ruby | 137 lines | 77 code | 10 blank | 50 comment | 8 complexity | 41b41deaf8da6eaece3507331f3c41f8 MD5 | raw file
  1. #======================================================================
  2. # HA Web Konsole (Hawk)
  3. # --------------------------------------------------------------------
  4. # A web-based GUI for managing and monitoring the
  5. # Pacemaker High-Availability cluster resource manager
  6. #
  7. # Copyright (c) 2009-2011 Novell Inc., Tim Serong <tserong@novell.com>
  8. # All Rights Reserved.
  9. #
  10. # This program is free software; you can redistribute it and/or modify
  11. # it under the terms of version 2 of the GNU General Public License as
  12. # published by the Free Software Foundation.
  13. #
  14. # This program is distributed in the hope that it would be useful, but
  15. # WITHOUT ANY WARRANTY; without even the implied warranty of
  16. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. #
  18. # Further, this software is distributed without any warranty that it is
  19. # free of the rightful claim of any third person regarding infringement
  20. # or the like. Any license provided herein, whether implied or
  21. # otherwise, applies only to this software file. Patent licenses, if
  22. # any, provided herein do not apply to combinations of this program with
  23. # other software, or any other product whatsoever.
  24. #
  25. # You should have received a copy of the GNU General Public License
  26. # along with this program; if not, write the Free Software Foundation,
  27. # Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  28. #
  29. #======================================================================
  30. # Random utilities
  31. module Util
  32. # Derived from Ruby 1.8's and 1.9's lib/open3.rb. Returns
  33. # [stdin, stdout, stderr, thread]. thread.value.exitstatus
  34. # has the exit value of the child, but if you're calling it
  35. # in non-block form, you need to close stdin, out and err
  36. # else the process won't be complete when you try to get the
  37. # exit status.
  38. def popen3(*cmd)
  39. pw = IO::pipe # pipe[0] for read, pipe[1] for write
  40. pr = IO::pipe
  41. pe = IO::pipe
  42. pid = fork{
  43. # child
  44. pw[1].close
  45. STDIN.reopen(pw[0])
  46. pw[0].close
  47. pr[0].close
  48. STDOUT.reopen(pr[1])
  49. pr[1].close
  50. pe[0].close
  51. STDERR.reopen(pe[1])
  52. pe[1].close
  53. exec(*cmd)
  54. }
  55. wait_thr = Process.detach(pid)
  56. pw[0].close
  57. pr[1].close
  58. pe[1].close
  59. pi = [pw[1], pr[0], pe[0], wait_thr]
  60. pw[1].sync = true
  61. if defined? yield
  62. begin
  63. return yield(*pi)
  64. ensure
  65. pi.each{|p| p.close if p.respond_to?(:closed) && !p.closed?}
  66. wait_thr.join
  67. end
  68. end
  69. pi
  70. end
  71. module_function :popen3
  72. # Like popen3, but via /usr/sbin/hawk_invoke
  73. def run_as(user, *cmd)
  74. # crm shell always wants to open/generate help index, so we
  75. # let it use a group-writable subdirectory of our tmp directory
  76. # so unprivileged users can actually invoke crm without warnings
  77. ENV['HOME'] = File.join(RAILS_ROOT, 'tmp', 'home')
  78. pi = popen3('/usr/sbin/hawk_invoke', user, *cmd)
  79. if defined? yield
  80. begin
  81. return yield(*pi)
  82. ensure
  83. pi.each{|p| p.close if p.respond_to?(:closed) && !p.closed?}
  84. end
  85. end
  86. pi
  87. end
  88. module_function :run_as
  89. # Like %x[...], but without risk of shell injection. Returns STDOUT
  90. # as a string. STDERR is ignored. $?.exitstatus is set appropriately.
  91. # May block indefinitely if the command executed is expecting something
  92. # on STDIN (untested)
  93. def safe_x(*cmd)
  94. pr = IO::pipe # pipe[0] for read, pipe[1] for write
  95. pe = IO::pipe
  96. pid = fork{
  97. # child
  98. fork{
  99. # grandchild
  100. pr[0].close
  101. STDOUT.reopen(pr[1])
  102. pr[1].close
  103. pe[0].close
  104. STDERR.reopen(pe[1])
  105. pe[1].close
  106. exec(*cmd)
  107. }
  108. Process.wait
  109. exit!($?.exitstatus)
  110. }
  111. Process.waitpid(pid)
  112. pr[1].close
  113. pe[1].close
  114. out = pr[0].read()
  115. pr[0].close
  116. out
  117. end
  118. module_function :safe_x
  119. # Gives back a string, boolean if value is "true" or "false", or nil
  120. # if initial value was nil (or boolean false) and there's no default
  121. # TODO(should): be nice to get integers auto-converted too
  122. def unstring(v, default = nil)
  123. v ||= default
  124. ['true', 'false'].include?(v.class == String ? v.downcase : v) ? v.downcase == 'true' : v
  125. end
  126. module_function :unstring
  127. end