Module Ohai::Mixin::Command
In: lib/ohai/mixin/command.rb
Mixlib::CLI Application System RuntimeError Exec Config Log lib/ohai/config.rb lib/ohai/log.rb lib/ohai/system.rb lib/ohai/application.rb Command FromFile Mixin lib/ohai/exception.rb Exceptions Ohai dot/m_128_0.png

Methods

Public Instance methods

This is taken directly from Ara T Howard‘s Open4 library, and then modified to suit the needs of Ohai. Any bugs here are most likely my own, and not Ara‘s.

The original appears in external/open4.rb in its unmodified form.

Thanks Ara!

[Source]

     # File lib/ohai/mixin/command.rb, line 99
 99:       def popen4(cmd, args={}, &b)
100:         
101:         args[:user] ||= nil
102:         unless args[:user].kind_of?(Integer)
103:           args[:user] = Etc.getpwnam(args[:user]).uid if args[:user]
104:         end
105:         args[:group] ||= nil
106:         unless args[:group].kind_of?(Integer)
107:           args[:group] = Etc.getgrnam(args[:group]).gid if args[:group]
108:         end
109:         args[:environment] ||= {}
110: 
111:         # Default on C locale so parsing commands output can be done
112:         # independently of the node's default locale.
113:         # "LC_ALL" could be set to nil, in which case we also must ignore it.
114:         unless args[:environment].has_key?("LC_ALL")
115:           args[:environment]["LC_ALL"] = "C"
116:         end
117:         
118:         pw, pr, pe, ps = IO.pipe, IO.pipe, IO.pipe, IO.pipe
119: 
120:         verbose = $VERBOSE
121:         begin
122:           $VERBOSE = nil
123:           ps.last.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
124: 
125:           cid = fork {
126:             pw.last.close
127:             STDIN.reopen pw.first
128:             pw.first.close
129: 
130:             pr.first.close
131:             STDOUT.reopen pr.last
132:             pr.last.close
133: 
134:             pe.first.close
135:             STDERR.reopen pe.last
136:             pe.last.close
137: 
138:             STDOUT.sync = STDERR.sync = true
139: 
140:             if args[:user]
141:               Process.euid = args[:user]
142:               Process.uid = args[:user]
143:             end
144:             
145:             if args[:group]
146:               Process.egid = args[:group]
147:               Process.gid = args[:group]
148:             end
149:             
150:             args[:environment].each do |key,value|
151:               ENV[key] = value
152:             end
153:             
154:             begin
155:               if cmd.kind_of?(Array)
156:                 exec(*cmd)
157:               else
158:                 exec(cmd)
159:               end
160:               raise 'forty-two' 
161:             rescue Exception => e
162:               Marshal.dump(e, ps.last)
163:               ps.last.flush
164:             end
165:             ps.last.close unless (ps.last.closed?)
166:             exit!
167:           }
168:         ensure
169:           $VERBOSE = verbose
170:         end
171: 
172:         [pw.first, pr.last, pe.last, ps.last].each{|fd| fd.close}
173: 
174:         begin
175:           e = Marshal.load ps.first
176:           # If we get here, exec failed. Collect status of child to prevent
177:           # zombies.
178:           Process.waitpid(cid)
179:           raise(Exception === e ? e : "unknown failure!")
180:         rescue EOFError # If we get an EOF error, then the exec was successful
181:           42
182:         ensure
183:           ps.first.close
184:         end
185: 
186:         pw.last.sync = true
187: 
188:         pi = [pw.last, pr.first, pe.first]
189: 
190:         if b 
191:           begin
192:             b[cid, *pi]
193:             Process.waitpid2(cid).last
194:           ensure
195:             pi.each{|fd| fd.close unless fd.closed?}
196:           end
197:         else
198:           [cid, pw.last, pr.first, pe.first]
199:         end
200:       end

[Source]

    # File lib/ohai/mixin/command.rb, line 31
31:       def run_command(args={})         
32:         if args.has_key?(:creates)
33:           if File.exists?(args[:creates])
34:             Ohai::Log.debug("Skipping #{args[:command]} - creates #{args[:creates]} exists.")
35:             return false
36:           end
37:         end
38:         
39:         stdout_string = nil
40:         stderr_string = nil
41:                 
42:         args[:cwd] ||= Dir.tmpdir        
43:         unless File.directory?(args[:cwd])
44:           raise Ohai::Exceptions::Exec, "#{args[:cwd]} does not exist or is not a directory"
45:         end
46:         
47:         status = nil
48:         Dir.chdir(args[:cwd]) do
49:           if args[:timeout]
50:             begin
51:               Timeout.timeout(args[:timeout]) do
52:                 status, stdout_string, stderr_string = systemu(args[:command])
53:               end
54:             rescue Exception => e
55:               Ohai::Log.error("#{args[:command_string]} exceeded timeout #{args[:timeout]}")
56:               raise(e)
57:             end
58:           else
59:             status, stdout_string, stderr_string = systemu(args[:command])
60:           end
61: 
62:           # systemu returns 42 when it hits unexpected errors
63:           if status.exitstatus == 42 and stderr_string == ""
64:             stderr_string = "Failed to run: #{args[:command]}, assuming command not found"
65:             Ohai::Log.debug(stderr_string)          
66:           end
67: 
68:           if stdout_string
69:             Ohai::Log.debug("---- Begin #{args[:command]} STDOUT ----")
70:             Ohai::Log.debug(stdout_string.strip)
71:             Ohai::Log.debug("---- End #{args[:command]} STDOUT ----")
72:           end
73:           if stderr_string
74:             Ohai::Log.debug("---- Begin #{args[:command]} STDERR ----")
75:             Ohai::Log.debug(stderr_string.strip)
76:             Ohai::Log.debug("---- End #{args[:command]} STDERR ----")
77:           end
78:         
79:           args[:returns] ||= 0
80:           args[:no_status_check] ||= false
81:           if status.exitstatus != args[:returns] and not args[:no_status_check]
82:             raise Ohai::Exceptions::Exec, "#{args[:command_string]} returned #{status.exitstatus}, expected #{args[:returns]}"
83:           else
84:             Ohai::Log.debug("Ran #{args[:command_string]} (#{args[:command]}) returned #{status.exitstatus}")
85:           end
86:         end
87:         return status, stdout_string, stderr_string
88:       end

[Validate]