File: run.rb

package info (click to toggle)
ruby-god 0.12.1-1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 752 kB
  • sloc: ruby: 5,913; ansic: 217; makefile: 3
file content (168 lines) | stat: -rw-r--r-- 4,201 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
module God
  module CLI

    class Run
      def initialize(options)
        @options = options

        dispatch
      end

      def dispatch
        # have at_exit start god
        $run = true

        if @options[:syslog]
          require 'god/sys_logger'
        end

        # run
        if @options[:daemonize]
          run_daemonized
        else
          run_in_front
        end
      end

      def attach
        process = System::Process.new(@options[:attach])
        Thread.new do
          loop do
            unless process.exists?
              applog(nil, :info, "Going down because attached process #{@options[:attach]} exited")
              exit!
            end
            sleep 5
          end
        end
      end

      def default_run
        # make sure we have STDIN/STDOUT redirected immediately
        setup_logging

        # start attached pid watcher if necessary
        if @options[:attach]
          self.attach
        end

        if @options[:port]
          God.port = @options[:port]
        end

        if @options[:events]
          God::EventHandler.load
        end

        # set log level, defaults to WARN
        if @options[:log_level]
          God.log_level = @options[:log_level]
        else
          God.log_level = @options[:daemonize] ? :warn : :info
        end

        if @options[:config]
          if !@options[:config].include?('*') && !File.exist?(@options[:config])
            abort "File not found: #{@options[:config]}"
          end

          # start the event handler
          God::EventHandler.start if God::EventHandler.loaded?

          load_config @options[:config]
        end
        setup_logging
      end

      def run_in_front
        require 'god'

        default_run
      end

      def run_daemonized
        # trap and ignore SIGHUP
        Signal.trap('HUP') {}

        pid = fork do
          begin
            require 'god'

            # set pid if requested
            if @options[:pid] # and as deamon
              God.pid = @options[:pid]
            end

            default_run

            unless God::EventHandler.loaded?
              puts
              puts "***********************************************************************"
              puts "*"
              puts "* Event conditions are not available for your installation of god."
              puts "* You may still use and write custom conditions using the poll system"
              puts "*"
              puts "***********************************************************************"
              puts
            end

          rescue => e
            puts e.message
            puts e.backtrace.join("\n")
            abort "There was a fatal system error while starting god (see above)"
          end
        end

        if @options[:pid]
          File.open(@options[:pid], 'w') { |f| f.write pid }
        end

        ::Process.detach pid

        exit
      end

      def setup_logging
        log_file = God.log_file
        log_file = File.expand_path(@options[:log]) if @options[:log]
        log_file = "/dev/null" if !log_file && @options[:daemonize]
        if log_file
          puts "Sending output to log file: #{log_file}" unless @options[:daemonize]

          # reset file descriptors
          STDIN.reopen "/dev/null"
          STDOUT.reopen(log_file, "a")
          STDERR.reopen STDOUT
          STDOUT.sync = true
        end
      end

      def load_config(config)
        files = File.directory?(config) ? Dir['**/*.god'] : Dir[config]
        abort "No files could be found" if files.empty?
        files.each do |god_file|
          unless load_god_file(god_file)
            abort "File '#{god_file}' could not be loaded"
          end
        end
      end

      def load_god_file(god_file)
        applog(nil, :info, "Loading #{god_file}")
        load File.expand_path(god_file)
        true
      rescue Exception => e
        if e.instance_of?(SystemExit)
          raise
        else
          puts "There was an error in #{god_file}"
          puts "\t" + e.message
          puts "\t" + e.backtrace.join("\n\t")
          false
        end
      end

    end # Run

  end
end