| Class | Dsadmin::System |
| In: |
lib/dsadmin/system.rb
|
| Parent: | Object |
System abstraction class
Singleton with convenience methods for all kinds of system-specific stuff. If something is covered here, don‘t even think of doing it manually — that would mess up the testing environment and probably also the system as such.
| See also: | SystemCommand |
| See also: | SystemPath |
| See also: | CoreClient |
| OS_UNKNOWN | = | 0 |
| OS_LINUX | = | 1 |
| OS_SOLARIS | = | 2 |
| OS_FREEBSD | = | 3 |
| disable_uid_change | [RW] | |
| original_uid | [R] | |
| os_type | [R] |
# File lib/dsadmin/system.rb, line 175
175: def initialize
176: @euid_mutex = Mutex.new
177: @original_uid = nil
178: @os_type = getOSType
179: end
Drop our EUID/EGID to safe values (nobody/nogroup)
# File lib/dsadmin/system.rb, line 58
58: def dropPrivileges
59: setuidgid('nobody', 'nogroup')
60: end
Kill a child process.
First tries a SIGTERM, and if that does not help a SIGKILL
| aChildOrThread: | Either the PID of the child process, or the thread object that spawned the child |
| aTimeout: | Seconds to wait for termination (total time for both signale) |
# File lib/dsadmin/system.rb, line 98
98: def killChild(aChildOrThread = Thread.current, aTimeout = 5)
99: if(aChildOrThread.kind_of?(Thread))
100: pid = aChildOrThread[:exec_pid]
101: else
102: pid = aChildOrThread
103: end
104:
105: return unless(pid)
106:
107: ['SIGTERM', 'SIGKILL'].each { |sig|
108: runAs('root') {
109: Process.kill(sig, pid)
110: }
111:
112: begin
113: timeout(aTimeout / 2.0) { #/
114: Process.waitpid(pid)
115: }
116: rescue TimeoutError
117: next # try next signal
118: else
119: break # success => no more killing
120: end
121: }
122:
123: aChildOrThread[:exec_pid] = nil if(aChildOrThread.kind_of?(Thread))
124: end
Get the current time (as per Time.now).
Abstraction to allow for easier testing. Use it !!
# File lib/dsadmin/system.rb, line 159
159: def now
160: Time.now
161: end
Run the given block (always give a block) as the specified user/group.
Both numerical IDs and Names (Strings) can be used for aUserID and aGroupID.
# File lib/dsadmin/system.rb, line 73
73: def runAs(aUserID, aGroupID = Process.egid)
74: assertTrue(block_given?)
75:
76: begin
77: # We make sure that no other thread can be executed
78: # as long as the process has a privileged (E)UID
79: Thread.critical = true
80:
81: setuidgid(aUserID, aGroupID)
82: yield
83: ensure
84: dropPrivileges
85: Thread.critical = false
86: end
87: end
Determine the current load average of the system (returns a Float).
# File lib/dsadmin/system.rb, line 128
128: def sysload
129: stat = File.stat('/proc/loadavg')
130: tmp = nil
131:
132: if(stat.readable?)
133: crit = Thread.critical
134: begin
135: Thread.critical = true
136: tmp = File.read('/proc/loadavg')
137: ensure
138: Thread.critical = crit
139: end
140: else
141: tmp = `uptime`
142: tmp = tmp[/load average:\s*(\d+\.\d+)/]
143: end
144:
145: tmp = tmp[/(\d+\.\d+)/]
146: return tmp.to_f
147: end
Get a human-readable and canonical string representation of the given time
# File lib/dsadmin/system.rb, line 165
165: def time2string(aTime = now)
166: aTime.gmtime.strftime('%Y-%m-%d %H:%M:%S +0000')
167: end
# File lib/dsadmin/system.rb, line 211
211: def getOSType
212: case(Config::CONFIG['host'])
213: when /linux/ : return OS_LINUX
214: when /solaris/ : return OS_SOLARIS
215: when /freebsd/ : return OS_FREEBSD
216: else
217: log.warning("Found unrecognizes OS type '#{Config::CONFIG['host']}'")
218: return OS_UNKNOWN
219: end
220: end
# File lib/dsadmin/system.rb, line 182
182: def setuidgid(aUserID, aGroupID)
183: @original_uid ||= Process.uid
184: return if disable_uid_change
185: requireTrue((Process.uid == 0) || (@original_uid == 0))
186:
187: # puts "setuidgid: #{Process.uid}:#{Process.gid} => #{aUserID}:#{aGroupID}"
188: @euid_mutex.synchronize {
189: Process.uid = 0 if(os_type == OS_LINUX)
190: Process.euid = 0
191:
192: if(aGroupID.kind_of?(Integer))
193: Process.egid = aGroupID
194: Process.gid = aGroupID if(os_type == OS_LINUX)
195: else
196: Process.egid = Etc.getgrnam(aGroupID).gid
197: Process.gid = Etc.getgrnam(aGroupID).gid if(os_type == OS_LINUX)
198: end
199:
200: if(aUserID.kind_of?(Integer))
201: Process.euid = aUserID
202: Process.uid = aUserID if(os_type == OS_LINUX)
203: else
204: Process.euid = Etc.getpwnam(aUserID).uid
205: Process.uid = Etc.getpwnam(aUserID).uid if(os_type == OS_LINUX)
206: end
207: }
208: end