| Class | Dsadmin::Admind::AdminDaemon |
| In: |
lib/dsadmin/admind/AdminDaemon.rb
|
| Parent: | Object |
# File lib/dsadmin/admind/AdminDaemon.rb, line 116
116: def initialize
117: @running = false
118: @in_shutdown = false
119: @shutdown_procs = []
120: @main_thread = Thread.current
121: end
Start the application, kick off processing and wait until shutdown
# File lib/dsadmin/admind/AdminDaemon.rb, line 48
48: def run(options)
49: @main_thread = Thread.current
50: startup(options)
51:
52: # The real processing (including shutdown) is handled in a separate thread,
53: # so we just have to wait forever here
54: sleep(5) while @running
55: end
# File lib/dsadmin/admind/AdminDaemon.rb, line 86
86: def shutdown(do_cascade = false, do_restart = false)
87: return if @in_shutdown
88: return unless @running
89: @in_shutdown = true
90: @running = false
91:
92: Dsadmin::Logger.instance.notice("Shutting down ...")
93:
94: shutdown_services(do_cascade, do_restart)
95:
96: ActiveLDAP::Base.close
97:
98: # $stderr.puts "services are down"
99: # just to be sure
100: ObjectSpace.each_object(BasicSocket) { |sock|
101: next if sock.closed?
102: $stderr.puts "Closing leftover socket #{sock}"
103: sock.close rescue nil
104: }
105:
106: # $stderr.puts("Exiting")
107: do_restart ? restart : @main_thread.wakeup
108: end
Start the application. Returns once everything is happily running in the background. Typically you‘ll rather run the "run" method instead.
# File lib/dsadmin/admind/AdminDaemon.rb, line 60
60: def startup(options)
61: return if @running
62: return if @in_shutdown
63: @running = true
64:
65: unless((defined? TEST_MODE) || (Process.euid == 0))
66: $stderr.puts "This has to be run with 'root' privileges"
67: exit(1)
68: end
69:
70: begin
71: start_services(options)
72:
73: daemonize if options.do_daemonize
74: Dsadmin::System.instance.dropPrivileges
75: init_sig_handler
76:
77: send_startup_request
78: rescue Exception => e
79: puts "#{e.class.name}: #{e.message}"
80: puts " " + e.backtrace.join("\n ")
81: shutdown(false, false)
82: end
83: end
# File lib/dsadmin/admind/AdminDaemon.rb, line 212
212: def daemonize()
213: exit if fork
214:
215: #$stderr.puts("Starting child")
216: Process.setsid()
217: Dir.chdir("/")
218: File.umask(0)
219: end
# File lib/dsadmin/admind/AdminDaemon.rb, line 183
183: def init_db_layer(environment)
184: env = environment || 'development'
185:
186: arconfig = File.open(ConfigManager.instance.localpath("config/database.yml")) { |f| YAML::load(f) }
187: ActiveRecord::Base.establish_connection(arconfig[env])
188: ActiveRecord::Base.allow_concurrency = true
189: ActiveRecord::Base.verification_timeout = 14400
190:
191: ldapconfig = File.open(ConfigManager.instance.localpath("config/ldap.yml")) { |f| YAML::load(f) }
192: cfg = Hash.new
193: ldapconfig[env].each { |key, val| cfg[key.to_sym] = val }
194: cfg[:return_objects] = true
195: ActiveLDAP::Base.connect(cfg)
196: end
# File lib/dsadmin/admind/AdminDaemon.rb, line 222
222: def init_sig_handler
223: Kernel.trap("TERM") { AdminDaemon.instance.shutdown(false, false) }
224: Kernel.trap("INT") { AdminDaemon.instance.shutdown(false, false) }
225: end
# File lib/dsadmin/admind/AdminDaemon.rb, line 199
199: def restart
200: rubycmd = File.join(::Config::CONFIG['bindir'], "ruby")
201:
202: argv = $* - ['--d', '--daemon', '--daemonize'] # make sure the PID doesn't change
203: args = [ConfigManager.instance.localpath($0)] + argv
204:
205: # $stderr.puts("Restarting admind as '#{rubycmd} '#{args.join(' ')}'")
206: System.instance.runAs(0, 0) {
207: exec(rubycmd, *args)
208: }
209: end
# File lib/dsadmin/admind/AdminDaemon.rb, line 163
163: def send_startup_request
164: cfg = ConfigManager.instance
165: log = Dsadmin::Logger.instance
166:
167: if(cfg.master? && (not defined? TEST_MODE))
168: req = Request.new_simple(:meta, :startup)
169:
170: Thread.new {
171: begin
172: res = RequestProcessor.instance.process(req)
173: log.notice("Status of startup request: #{res.status}")
174: #puts res.data
175: rescue StandardError => xcept
176: log.bug(xcept)
177: end
178: }
179: end
180: end
# File lib/dsadmin/admind/AdminDaemon.rb, line 155
155: def shutdown_services(do_cascade, do_restart)
156: while(@shutdown_procs.size > 0)
157: sdproc = @shutdown_procs.pop
158: sdproc.call(do_cascade, do_restart)
159: end
160: end
Start all the main parts of this app. This also registers shutdown handlers for all started services (in the correct order), for easy shutdown.
Exceptions from the services’ startup routines are simply passed through and have to be handled by the caller.
# File lib/dsadmin/admind/AdminDaemon.rb, line 130
130: def start_services(options)
131: ConfigManager.setup(options.instanceid, options.cfgfile)
132:
133: init_db_layer(options.environment)
134:
135: log = Dsadmin::Logger.instance
136: log.run
137: @shutdown_procs << lambda { log.shutdown }
138:
139: rproc = RequestProcessor.instance
140: rproc.startup
141: @shutdown_procs << lambda { |do_cascade, do_restart| rproc.shutdown(do_cascade, do_restart) }
142:
143: if(ConfigManager.instance.master?)
144: cron = Cron.instance
145: cron.run
146: @shutdown_procs << lambda { cron.shutdown }
147: end
148:
149: listener = SocketListener.new
150: listener.startup
151: @shutdown_procs << lambda { listener.shutdown }
152: end