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

[Source]

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

[Validate]