Class: DevDNSd::Application

Inherits:
Process::Daemon
  • Object
show all
Includes:
Aliases, OSX, Server, System
Defined in:
lib/devdnsd/application.rb

Overview

The main DevDNSd application.

Constant Summary collapse

ANY_REQUEST =

Class for ANY DNS request.

Resolv::DNS::Resource::IN::ANY
ANY_CLASSES =

List of classes handled in case of DNS request with resource class ANY.

[
  Resolv::DNS::Resource::IN::A, Resolv::DNS::Resource::IN::AAAA, Resolv::DNS::Resource::IN::ANY, Resolv::DNS::Resource::IN::CNAME,
  Resolv::DNS::Resource::IN::HINFO, Resolv::DNS::Resource::IN::MINFO, Resolv::DNS::Resource::IN::MX, Resolv::DNS::Resource::IN::NS,
  Resolv::DNS::Resource::IN::PTR, Resolv::DNS::Resource::IN::SOA, Resolv::DNS::Resource::IN::TXT
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from OSX

#action_add, #action_install, #action_remove, #action_uninstall, #dns_update, #execute_command, #launch_agent_path, #osx?, #resolver_path

Methods included from System

#action_restart, #action_start, #action_status, #action_stop, #daemon_name, #log_directory, #log_file_path, #process_file_path, #working_directory

Methods included from Server

#perform_server, #process_rule, #process_rule_in_classes

Methods included from Aliases

#compute_addresses, #ipv4?, #ipv6?, #manage_address, #manage_aliases

Constructor Details

#initialize(command, locale) ⇒ Application

Creates a new application.

Parameters:

  • command (Bovem::Command)

    The current Bovem command.

  • locale (Symbol)

    The locale to use for the application.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/devdnsd/application.rb', line 50

def initialize(command, locale)
  @i18n = Bovem::I18n.new(locale, root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/")
  @locale = locale
  @command = command
  options = load_options

  # Setup logger
  create_logger(options)

  # Open configuration
  read_configuration(options)

  super(working_directory)
  self
end

Instance Attribute Details

#:i18n(: i18n) ⇒ Bovem::I18n (readonly)

Returns A localizer object.

Returns:

  • (Bovem::I18n)

    A localizer object.



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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/devdnsd/application.rb', line 23

class Application < Process::Daemon
  # Class for ANY DNS request.
  ANY_REQUEST = Resolv::DNS::Resource::IN::ANY

  # List of classes handled in case of DNS request with resource class ANY.
  ANY_CLASSES = [
    Resolv::DNS::Resource::IN::A, Resolv::DNS::Resource::IN::AAAA, Resolv::DNS::Resource::IN::ANY, Resolv::DNS::Resource::IN::CNAME,
    Resolv::DNS::Resource::IN::HINFO, Resolv::DNS::Resource::IN::MINFO, Resolv::DNS::Resource::IN::MX, Resolv::DNS::Resource::IN::NS,
    Resolv::DNS::Resource::IN::PTR, Resolv::DNS::Resource::IN::SOA, Resolv::DNS::Resource::IN::TXT
  ].freeze

  include DevDNSd::Aliases
  include DevDNSd::Server
  include DevDNSd::System
  include DevDNSd::OSX

  attr_reader :config
  attr_reader :command
  attr_accessor :logger
  attr_reader :locale
  attr_reader :i18n
  attr_reader :server

  # Creates a new application.
  #
  # @param command [Bovem::Command] The current Bovem command.
  # @param locale [Symbol] The locale to use for the application.
  def initialize(command, locale)
    @i18n = Bovem::I18n.new(locale, root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/")
    @locale = locale
    @command = command
    options = load_options

    # Setup logger
    create_logger(options)

    # Open configuration
    read_configuration(options)

    super(working_directory)
    self
  end

  # Stops the server.
  def shutdown
    server.actors.first.links.each(&:terminate) if server
  end

  # Gets the current logger of the application.
  #
  # @param force [Boolean] If to force recreation of the logger.
  # @return [Logger] The current logger of the application.
  def logger(force = false)
    @logger = nil if force
    @logger ||= Bovem::Logger.create(@config.foreground ? $stdout : @config.log_file, level: @config.log_level, formatter: @log_formatter)
  end

  # This method is called when the server starts. By default is a no-op.
  #
  # @return [NilClass] `nil`.
  def on_start
  end

  # This method is called when the server stop.
  #
  # @return [NilClass] `nil`.
  def on_stop
  end

  # Returns a unique (singleton) instance of the application.
  #
  # @param command [Bovem::Command] The current Bovem command.
  # @param locale [Symbol] The locale to use for the application.
  # @param force [Boolean] If to force recreation of the instance.
  # @return [Application] The unique (singleton) instance of the application.
  def self.instance(command = nil, locale = nil, force = false)
    @instance = nil if force
    @instance ||= DevDNSd::Application.new(command, locale) if command
    @instance
  end

  # Runs the application in foreground.
  #
  # @see #perform_server
  def self.run
    instance.perform_server
  end

  # Stops the application.
  def self.quit
    instance.shutdown
  rescue
    Kernel.exit(1)
  end

  # Check if the current implementation supports DevDNSd.
  def self.check_ruby_implementation
    if defined?(JRuby)
      Kernel.puts(Bovem::I18n.new(root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/").no_jruby)
      Kernel.exit(0)
    end
  end

  private

  # :nodoc:
  def load_options
    @command.application.get_options.reject { |_, v| v.nil? }.merge(@command.get_options.reject { |_, v| v.nil? })
  end

  # :nodoc:
  def create_logger(options)
    warn_failure = false
    orig_file = file = Bovem::Logger.get_real_file(options["log_file"]) || Bovem::Logger.default_file

    if file.is_a?(String)
      file, warn_failure = load_logger(File.absolute_path(File.expand_path(file)), options)
    end

    finalize_create_logger(file, orig_file, warn_failure)
  end

  # :nodoc:
  def load_logger(file, options)
    warn_failure = false

    begin
      FileUtils.mkdir_p(File.dirname(file))
      @logger = Bovem::Logger.create(file, level: ::Logger::INFO)
    rescue
      options["log_file"] = "STDOUT"
      file = $stdout
      warn_failure = true
    end

    [file, warn_failure]
  end

  # :nodoc:
  def finalize_create_logger(file, orig_file, warn_failure)
    @logger = Bovem::Logger.create(file, level: ::Logger::INFO)
    @logger.warn(replace_markers(i18n.logging_failed(orig_file))) if @logger && warn_failure
    @logger
  end

  # :nodoc:
  def read_configuration(options)
    path = ::File.absolute_path(File.expand_path(options["configuration"]))

    begin
      @config = DevDNSd::Configuration.new(path, options, @logger)
      ensure_directory_for(@config.log_file) if @config.log_file.is_a?(String)
      ensure_directory_for(@config.pid_file)
      @logger = logger(true)
    rescue Bovem::Errors::InvalidConfiguration => e
      log_failed_configuration(path, e)
      shutdown
    end
  end

  # :nodoc:
  def ensure_directory_for(path)
    FileUtils.mkdir_p(File.dirname(path))
  rescue
    @logger.warn(replace_markers(i18n.invalid_directory(File.dirname(path))))
    shutdown
    Kernel.exit(1)
  end

  # :nodoc:
  def log_failed_configuration(path, exception)
    logger = Bovem::Logger.create($stderr)
    logger.fatal(exception.message)
    logger.warn(replace_markers(i18n.application_create_config(path)))
  end
end

#commandBovem::Command (readonly)

Returns The Bovem command.

Returns:

  • (Bovem::Command)

    The Bovem command.



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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/devdnsd/application.rb', line 23

class Application < Process::Daemon
  # Class for ANY DNS request.
  ANY_REQUEST = Resolv::DNS::Resource::IN::ANY

  # List of classes handled in case of DNS request with resource class ANY.
  ANY_CLASSES = [
    Resolv::DNS::Resource::IN::A, Resolv::DNS::Resource::IN::AAAA, Resolv::DNS::Resource::IN::ANY, Resolv::DNS::Resource::IN::CNAME,
    Resolv::DNS::Resource::IN::HINFO, Resolv::DNS::Resource::IN::MINFO, Resolv::DNS::Resource::IN::MX, Resolv::DNS::Resource::IN::NS,
    Resolv::DNS::Resource::IN::PTR, Resolv::DNS::Resource::IN::SOA, Resolv::DNS::Resource::IN::TXT
  ].freeze

  include DevDNSd::Aliases
  include DevDNSd::Server
  include DevDNSd::System
  include DevDNSd::OSX

  attr_reader :config
  attr_reader :command
  attr_accessor :logger
  attr_reader :locale
  attr_reader :i18n
  attr_reader :server

  # Creates a new application.
  #
  # @param command [Bovem::Command] The current Bovem command.
  # @param locale [Symbol] The locale to use for the application.
  def initialize(command, locale)
    @i18n = Bovem::I18n.new(locale, root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/")
    @locale = locale
    @command = command
    options = load_options

    # Setup logger
    create_logger(options)

    # Open configuration
    read_configuration(options)

    super(working_directory)
    self
  end

  # Stops the server.
  def shutdown
    server.actors.first.links.each(&:terminate) if server
  end

  # Gets the current logger of the application.
  #
  # @param force [Boolean] If to force recreation of the logger.
  # @return [Logger] The current logger of the application.
  def logger(force = false)
    @logger = nil if force
    @logger ||= Bovem::Logger.create(@config.foreground ? $stdout : @config.log_file, level: @config.log_level, formatter: @log_formatter)
  end

  # This method is called when the server starts. By default is a no-op.
  #
  # @return [NilClass] `nil`.
  def on_start
  end

  # This method is called when the server stop.
  #
  # @return [NilClass] `nil`.
  def on_stop
  end

  # Returns a unique (singleton) instance of the application.
  #
  # @param command [Bovem::Command] The current Bovem command.
  # @param locale [Symbol] The locale to use for the application.
  # @param force [Boolean] If to force recreation of the instance.
  # @return [Application] The unique (singleton) instance of the application.
  def self.instance(command = nil, locale = nil, force = false)
    @instance = nil if force
    @instance ||= DevDNSd::Application.new(command, locale) if command
    @instance
  end

  # Runs the application in foreground.
  #
  # @see #perform_server
  def self.run
    instance.perform_server
  end

  # Stops the application.
  def self.quit
    instance.shutdown
  rescue
    Kernel.exit(1)
  end

  # Check if the current implementation supports DevDNSd.
  def self.check_ruby_implementation
    if defined?(JRuby)
      Kernel.puts(Bovem::I18n.new(root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/").no_jruby)
      Kernel.exit(0)
    end
  end

  private

  # :nodoc:
  def load_options
    @command.application.get_options.reject { |_, v| v.nil? }.merge(@command.get_options.reject { |_, v| v.nil? })
  end

  # :nodoc:
  def create_logger(options)
    warn_failure = false
    orig_file = file = Bovem::Logger.get_real_file(options["log_file"]) || Bovem::Logger.default_file

    if file.is_a?(String)
      file, warn_failure = load_logger(File.absolute_path(File.expand_path(file)), options)
    end

    finalize_create_logger(file, orig_file, warn_failure)
  end

  # :nodoc:
  def load_logger(file, options)
    warn_failure = false

    begin
      FileUtils.mkdir_p(File.dirname(file))
      @logger = Bovem::Logger.create(file, level: ::Logger::INFO)
    rescue
      options["log_file"] = "STDOUT"
      file = $stdout
      warn_failure = true
    end

    [file, warn_failure]
  end

  # :nodoc:
  def finalize_create_logger(file, orig_file, warn_failure)
    @logger = Bovem::Logger.create(file, level: ::Logger::INFO)
    @logger.warn(replace_markers(i18n.logging_failed(orig_file))) if @logger && warn_failure
    @logger
  end

  # :nodoc:
  def read_configuration(options)
    path = ::File.absolute_path(File.expand_path(options["configuration"]))

    begin
      @config = DevDNSd::Configuration.new(path, options, @logger)
      ensure_directory_for(@config.log_file) if @config.log_file.is_a?(String)
      ensure_directory_for(@config.pid_file)
      @logger = logger(true)
    rescue Bovem::Errors::InvalidConfiguration => e
      log_failed_configuration(path, e)
      shutdown
    end
  end

  # :nodoc:
  def ensure_directory_for(path)
    FileUtils.mkdir_p(File.dirname(path))
  rescue
    @logger.warn(replace_markers(i18n.invalid_directory(File.dirname(path))))
    shutdown
    Kernel.exit(1)
  end

  # :nodoc:
  def log_failed_configuration(path, exception)
    logger = Bovem::Logger.create($stderr)
    logger.fatal(exception.message)
    logger.warn(replace_markers(i18n.application_create_config(path)))
  end
end

#configConfiguration (readonly)

Returns The Configuration of this application.

Returns:



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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/devdnsd/application.rb', line 23

class Application < Process::Daemon
  # Class for ANY DNS request.
  ANY_REQUEST = Resolv::DNS::Resource::IN::ANY

  # List of classes handled in case of DNS request with resource class ANY.
  ANY_CLASSES = [
    Resolv::DNS::Resource::IN::A, Resolv::DNS::Resource::IN::AAAA, Resolv::DNS::Resource::IN::ANY, Resolv::DNS::Resource::IN::CNAME,
    Resolv::DNS::Resource::IN::HINFO, Resolv::DNS::Resource::IN::MINFO, Resolv::DNS::Resource::IN::MX, Resolv::DNS::Resource::IN::NS,
    Resolv::DNS::Resource::IN::PTR, Resolv::DNS::Resource::IN::SOA, Resolv::DNS::Resource::IN::TXT
  ].freeze

  include DevDNSd::Aliases
  include DevDNSd::Server
  include DevDNSd::System
  include DevDNSd::OSX

  attr_reader :config
  attr_reader :command
  attr_accessor :logger
  attr_reader :locale
  attr_reader :i18n
  attr_reader :server

  # Creates a new application.
  #
  # @param command [Bovem::Command] The current Bovem command.
  # @param locale [Symbol] The locale to use for the application.
  def initialize(command, locale)
    @i18n = Bovem::I18n.new(locale, root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/")
    @locale = locale
    @command = command
    options = load_options

    # Setup logger
    create_logger(options)

    # Open configuration
    read_configuration(options)

    super(working_directory)
    self
  end

  # Stops the server.
  def shutdown
    server.actors.first.links.each(&:terminate) if server
  end

  # Gets the current logger of the application.
  #
  # @param force [Boolean] If to force recreation of the logger.
  # @return [Logger] The current logger of the application.
  def logger(force = false)
    @logger = nil if force
    @logger ||= Bovem::Logger.create(@config.foreground ? $stdout : @config.log_file, level: @config.log_level, formatter: @log_formatter)
  end

  # This method is called when the server starts. By default is a no-op.
  #
  # @return [NilClass] `nil`.
  def on_start
  end

  # This method is called when the server stop.
  #
  # @return [NilClass] `nil`.
  def on_stop
  end

  # Returns a unique (singleton) instance of the application.
  #
  # @param command [Bovem::Command] The current Bovem command.
  # @param locale [Symbol] The locale to use for the application.
  # @param force [Boolean] If to force recreation of the instance.
  # @return [Application] The unique (singleton) instance of the application.
  def self.instance(command = nil, locale = nil, force = false)
    @instance = nil if force
    @instance ||= DevDNSd::Application.new(command, locale) if command
    @instance
  end

  # Runs the application in foreground.
  #
  # @see #perform_server
  def self.run
    instance.perform_server
  end

  # Stops the application.
  def self.quit
    instance.shutdown
  rescue
    Kernel.exit(1)
  end

  # Check if the current implementation supports DevDNSd.
  def self.check_ruby_implementation
    if defined?(JRuby)
      Kernel.puts(Bovem::I18n.new(root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/").no_jruby)
      Kernel.exit(0)
    end
  end

  private

  # :nodoc:
  def load_options
    @command.application.get_options.reject { |_, v| v.nil? }.merge(@command.get_options.reject { |_, v| v.nil? })
  end

  # :nodoc:
  def create_logger(options)
    warn_failure = false
    orig_file = file = Bovem::Logger.get_real_file(options["log_file"]) || Bovem::Logger.default_file

    if file.is_a?(String)
      file, warn_failure = load_logger(File.absolute_path(File.expand_path(file)), options)
    end

    finalize_create_logger(file, orig_file, warn_failure)
  end

  # :nodoc:
  def load_logger(file, options)
    warn_failure = false

    begin
      FileUtils.mkdir_p(File.dirname(file))
      @logger = Bovem::Logger.create(file, level: ::Logger::INFO)
    rescue
      options["log_file"] = "STDOUT"
      file = $stdout
      warn_failure = true
    end

    [file, warn_failure]
  end

  # :nodoc:
  def finalize_create_logger(file, orig_file, warn_failure)
    @logger = Bovem::Logger.create(file, level: ::Logger::INFO)
    @logger.warn(replace_markers(i18n.logging_failed(orig_file))) if @logger && warn_failure
    @logger
  end

  # :nodoc:
  def read_configuration(options)
    path = ::File.absolute_path(File.expand_path(options["configuration"]))

    begin
      @config = DevDNSd::Configuration.new(path, options, @logger)
      ensure_directory_for(@config.log_file) if @config.log_file.is_a?(String)
      ensure_directory_for(@config.pid_file)
      @logger = logger(true)
    rescue Bovem::Errors::InvalidConfiguration => e
      log_failed_configuration(path, e)
      shutdown
    end
  end

  # :nodoc:
  def ensure_directory_for(path)
    FileUtils.mkdir_p(File.dirname(path))
  rescue
    @logger.warn(replace_markers(i18n.invalid_directory(File.dirname(path))))
    shutdown
    Kernel.exit(1)
  end

  # :nodoc:
  def log_failed_configuration(path, exception)
    logger = Bovem::Logger.create($stderr)
    logger.fatal(exception.message)
    logger.warn(replace_markers(i18n.application_create_config(path)))
  end
end

#i18nObject (readonly)

Returns the value of attribute i18n.



43
44
45
# File 'lib/devdnsd/application.rb', line 43

def i18n
  @i18n
end

#localeSymbol|nil (readonly)

Returns The current application locale.

Returns:

  • (Symbol|nil)

    The current application locale.



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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/devdnsd/application.rb', line 23

class Application < Process::Daemon
  # Class for ANY DNS request.
  ANY_REQUEST = Resolv::DNS::Resource::IN::ANY

  # List of classes handled in case of DNS request with resource class ANY.
  ANY_CLASSES = [
    Resolv::DNS::Resource::IN::A, Resolv::DNS::Resource::IN::AAAA, Resolv::DNS::Resource::IN::ANY, Resolv::DNS::Resource::IN::CNAME,
    Resolv::DNS::Resource::IN::HINFO, Resolv::DNS::Resource::IN::MINFO, Resolv::DNS::Resource::IN::MX, Resolv::DNS::Resource::IN::NS,
    Resolv::DNS::Resource::IN::PTR, Resolv::DNS::Resource::IN::SOA, Resolv::DNS::Resource::IN::TXT
  ].freeze

  include DevDNSd::Aliases
  include DevDNSd::Server
  include DevDNSd::System
  include DevDNSd::OSX

  attr_reader :config
  attr_reader :command
  attr_accessor :logger
  attr_reader :locale
  attr_reader :i18n
  attr_reader :server

  # Creates a new application.
  #
  # @param command [Bovem::Command] The current Bovem command.
  # @param locale [Symbol] The locale to use for the application.
  def initialize(command, locale)
    @i18n = Bovem::I18n.new(locale, root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/")
    @locale = locale
    @command = command
    options = load_options

    # Setup logger
    create_logger(options)

    # Open configuration
    read_configuration(options)

    super(working_directory)
    self
  end

  # Stops the server.
  def shutdown
    server.actors.first.links.each(&:terminate) if server
  end

  # Gets the current logger of the application.
  #
  # @param force [Boolean] If to force recreation of the logger.
  # @return [Logger] The current logger of the application.
  def logger(force = false)
    @logger = nil if force
    @logger ||= Bovem::Logger.create(@config.foreground ? $stdout : @config.log_file, level: @config.log_level, formatter: @log_formatter)
  end

  # This method is called when the server starts. By default is a no-op.
  #
  # @return [NilClass] `nil`.
  def on_start
  end

  # This method is called when the server stop.
  #
  # @return [NilClass] `nil`.
  def on_stop
  end

  # Returns a unique (singleton) instance of the application.
  #
  # @param command [Bovem::Command] The current Bovem command.
  # @param locale [Symbol] The locale to use for the application.
  # @param force [Boolean] If to force recreation of the instance.
  # @return [Application] The unique (singleton) instance of the application.
  def self.instance(command = nil, locale = nil, force = false)
    @instance = nil if force
    @instance ||= DevDNSd::Application.new(command, locale) if command
    @instance
  end

  # Runs the application in foreground.
  #
  # @see #perform_server
  def self.run
    instance.perform_server
  end

  # Stops the application.
  def self.quit
    instance.shutdown
  rescue
    Kernel.exit(1)
  end

  # Check if the current implementation supports DevDNSd.
  def self.check_ruby_implementation
    if defined?(JRuby)
      Kernel.puts(Bovem::I18n.new(root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/").no_jruby)
      Kernel.exit(0)
    end
  end

  private

  # :nodoc:
  def load_options
    @command.application.get_options.reject { |_, v| v.nil? }.merge(@command.get_options.reject { |_, v| v.nil? })
  end

  # :nodoc:
  def create_logger(options)
    warn_failure = false
    orig_file = file = Bovem::Logger.get_real_file(options["log_file"]) || Bovem::Logger.default_file

    if file.is_a?(String)
      file, warn_failure = load_logger(File.absolute_path(File.expand_path(file)), options)
    end

    finalize_create_logger(file, orig_file, warn_failure)
  end

  # :nodoc:
  def load_logger(file, options)
    warn_failure = false

    begin
      FileUtils.mkdir_p(File.dirname(file))
      @logger = Bovem::Logger.create(file, level: ::Logger::INFO)
    rescue
      options["log_file"] = "STDOUT"
      file = $stdout
      warn_failure = true
    end

    [file, warn_failure]
  end

  # :nodoc:
  def finalize_create_logger(file, orig_file, warn_failure)
    @logger = Bovem::Logger.create(file, level: ::Logger::INFO)
    @logger.warn(replace_markers(i18n.logging_failed(orig_file))) if @logger && warn_failure
    @logger
  end

  # :nodoc:
  def read_configuration(options)
    path = ::File.absolute_path(File.expand_path(options["configuration"]))

    begin
      @config = DevDNSd::Configuration.new(path, options, @logger)
      ensure_directory_for(@config.log_file) if @config.log_file.is_a?(String)
      ensure_directory_for(@config.pid_file)
      @logger = logger(true)
    rescue Bovem::Errors::InvalidConfiguration => e
      log_failed_configuration(path, e)
      shutdown
    end
  end

  # :nodoc:
  def ensure_directory_for(path)
    FileUtils.mkdir_p(File.dirname(path))
  rescue
    @logger.warn(replace_markers(i18n.invalid_directory(File.dirname(path))))
    shutdown
    Kernel.exit(1)
  end

  # :nodoc:
  def log_failed_configuration(path, exception)
    logger = Bovem::Logger.create($stderr)
    logger.fatal(exception.message)
    logger.warn(replace_markers(i18n.application_create_config(path)))
  end
end

#logger(force = false) ⇒ Logger

Gets the current logger of the application.

Parameters:

  • force (Boolean) (defaults to: false)

    If to force recreation of the logger.

Returns:

  • (Logger)

    The current logger of the application.



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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/devdnsd/application.rb', line 23

class Application < Process::Daemon
  # Class for ANY DNS request.
  ANY_REQUEST = Resolv::DNS::Resource::IN::ANY

  # List of classes handled in case of DNS request with resource class ANY.
  ANY_CLASSES = [
    Resolv::DNS::Resource::IN::A, Resolv::DNS::Resource::IN::AAAA, Resolv::DNS::Resource::IN::ANY, Resolv::DNS::Resource::IN::CNAME,
    Resolv::DNS::Resource::IN::HINFO, Resolv::DNS::Resource::IN::MINFO, Resolv::DNS::Resource::IN::MX, Resolv::DNS::Resource::IN::NS,
    Resolv::DNS::Resource::IN::PTR, Resolv::DNS::Resource::IN::SOA, Resolv::DNS::Resource::IN::TXT
  ].freeze

  include DevDNSd::Aliases
  include DevDNSd::Server
  include DevDNSd::System
  include DevDNSd::OSX

  attr_reader :config
  attr_reader :command
  attr_accessor :logger
  attr_reader :locale
  attr_reader :i18n
  attr_reader :server

  # Creates a new application.
  #
  # @param command [Bovem::Command] The current Bovem command.
  # @param locale [Symbol] The locale to use for the application.
  def initialize(command, locale)
    @i18n = Bovem::I18n.new(locale, root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/")
    @locale = locale
    @command = command
    options = load_options

    # Setup logger
    create_logger(options)

    # Open configuration
    read_configuration(options)

    super(working_directory)
    self
  end

  # Stops the server.
  def shutdown
    server.actors.first.links.each(&:terminate) if server
  end

  # Gets the current logger of the application.
  #
  # @param force [Boolean] If to force recreation of the logger.
  # @return [Logger] The current logger of the application.
  def logger(force = false)
    @logger = nil if force
    @logger ||= Bovem::Logger.create(@config.foreground ? $stdout : @config.log_file, level: @config.log_level, formatter: @log_formatter)
  end

  # This method is called when the server starts. By default is a no-op.
  #
  # @return [NilClass] `nil`.
  def on_start
  end

  # This method is called when the server stop.
  #
  # @return [NilClass] `nil`.
  def on_stop
  end

  # Returns a unique (singleton) instance of the application.
  #
  # @param command [Bovem::Command] The current Bovem command.
  # @param locale [Symbol] The locale to use for the application.
  # @param force [Boolean] If to force recreation of the instance.
  # @return [Application] The unique (singleton) instance of the application.
  def self.instance(command = nil, locale = nil, force = false)
    @instance = nil if force
    @instance ||= DevDNSd::Application.new(command, locale) if command
    @instance
  end

  # Runs the application in foreground.
  #
  # @see #perform_server
  def self.run
    instance.perform_server
  end

  # Stops the application.
  def self.quit
    instance.shutdown
  rescue
    Kernel.exit(1)
  end

  # Check if the current implementation supports DevDNSd.
  def self.check_ruby_implementation
    if defined?(JRuby)
      Kernel.puts(Bovem::I18n.new(root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/").no_jruby)
      Kernel.exit(0)
    end
  end

  private

  # :nodoc:
  def load_options
    @command.application.get_options.reject { |_, v| v.nil? }.merge(@command.get_options.reject { |_, v| v.nil? })
  end

  # :nodoc:
  def create_logger(options)
    warn_failure = false
    orig_file = file = Bovem::Logger.get_real_file(options["log_file"]) || Bovem::Logger.default_file

    if file.is_a?(String)
      file, warn_failure = load_logger(File.absolute_path(File.expand_path(file)), options)
    end

    finalize_create_logger(file, orig_file, warn_failure)
  end

  # :nodoc:
  def load_logger(file, options)
    warn_failure = false

    begin
      FileUtils.mkdir_p(File.dirname(file))
      @logger = Bovem::Logger.create(file, level: ::Logger::INFO)
    rescue
      options["log_file"] = "STDOUT"
      file = $stdout
      warn_failure = true
    end

    [file, warn_failure]
  end

  # :nodoc:
  def finalize_create_logger(file, orig_file, warn_failure)
    @logger = Bovem::Logger.create(file, level: ::Logger::INFO)
    @logger.warn(replace_markers(i18n.logging_failed(orig_file))) if @logger && warn_failure
    @logger
  end

  # :nodoc:
  def read_configuration(options)
    path = ::File.absolute_path(File.expand_path(options["configuration"]))

    begin
      @config = DevDNSd::Configuration.new(path, options, @logger)
      ensure_directory_for(@config.log_file) if @config.log_file.is_a?(String)
      ensure_directory_for(@config.pid_file)
      @logger = logger(true)
    rescue Bovem::Errors::InvalidConfiguration => e
      log_failed_configuration(path, e)
      shutdown
    end
  end

  # :nodoc:
  def ensure_directory_for(path)
    FileUtils.mkdir_p(File.dirname(path))
  rescue
    @logger.warn(replace_markers(i18n.invalid_directory(File.dirname(path))))
    shutdown
    Kernel.exit(1)
  end

  # :nodoc:
  def log_failed_configuration(path, exception)
    logger = Bovem::Logger.create($stderr)
    logger.fatal(exception.message)
    logger.warn(replace_markers(i18n.application_create_config(path)))
  end
end

#serverRubyDNS::RuleBasedServer (readonly)

Returns The server of this application.

Returns:

  • (RubyDNS::RuleBasedServer)

    The server of this application.



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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/devdnsd/application.rb', line 23

class Application < Process::Daemon
  # Class for ANY DNS request.
  ANY_REQUEST = Resolv::DNS::Resource::IN::ANY

  # List of classes handled in case of DNS request with resource class ANY.
  ANY_CLASSES = [
    Resolv::DNS::Resource::IN::A, Resolv::DNS::Resource::IN::AAAA, Resolv::DNS::Resource::IN::ANY, Resolv::DNS::Resource::IN::CNAME,
    Resolv::DNS::Resource::IN::HINFO, Resolv::DNS::Resource::IN::MINFO, Resolv::DNS::Resource::IN::MX, Resolv::DNS::Resource::IN::NS,
    Resolv::DNS::Resource::IN::PTR, Resolv::DNS::Resource::IN::SOA, Resolv::DNS::Resource::IN::TXT
  ].freeze

  include DevDNSd::Aliases
  include DevDNSd::Server
  include DevDNSd::System
  include DevDNSd::OSX

  attr_reader :config
  attr_reader :command
  attr_accessor :logger
  attr_reader :locale
  attr_reader :i18n
  attr_reader :server

  # Creates a new application.
  #
  # @param command [Bovem::Command] The current Bovem command.
  # @param locale [Symbol] The locale to use for the application.
  def initialize(command, locale)
    @i18n = Bovem::I18n.new(locale, root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/")
    @locale = locale
    @command = command
    options = load_options

    # Setup logger
    create_logger(options)

    # Open configuration
    read_configuration(options)

    super(working_directory)
    self
  end

  # Stops the server.
  def shutdown
    server.actors.first.links.each(&:terminate) if server
  end

  # Gets the current logger of the application.
  #
  # @param force [Boolean] If to force recreation of the logger.
  # @return [Logger] The current logger of the application.
  def logger(force = false)
    @logger = nil if force
    @logger ||= Bovem::Logger.create(@config.foreground ? $stdout : @config.log_file, level: @config.log_level, formatter: @log_formatter)
  end

  # This method is called when the server starts. By default is a no-op.
  #
  # @return [NilClass] `nil`.
  def on_start
  end

  # This method is called when the server stop.
  #
  # @return [NilClass] `nil`.
  def on_stop
  end

  # Returns a unique (singleton) instance of the application.
  #
  # @param command [Bovem::Command] The current Bovem command.
  # @param locale [Symbol] The locale to use for the application.
  # @param force [Boolean] If to force recreation of the instance.
  # @return [Application] The unique (singleton) instance of the application.
  def self.instance(command = nil, locale = nil, force = false)
    @instance = nil if force
    @instance ||= DevDNSd::Application.new(command, locale) if command
    @instance
  end

  # Runs the application in foreground.
  #
  # @see #perform_server
  def self.run
    instance.perform_server
  end

  # Stops the application.
  def self.quit
    instance.shutdown
  rescue
    Kernel.exit(1)
  end

  # Check if the current implementation supports DevDNSd.
  def self.check_ruby_implementation
    if defined?(JRuby)
      Kernel.puts(Bovem::I18n.new(root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/").no_jruby)
      Kernel.exit(0)
    end
  end

  private

  # :nodoc:
  def load_options
    @command.application.get_options.reject { |_, v| v.nil? }.merge(@command.get_options.reject { |_, v| v.nil? })
  end

  # :nodoc:
  def create_logger(options)
    warn_failure = false
    orig_file = file = Bovem::Logger.get_real_file(options["log_file"]) || Bovem::Logger.default_file

    if file.is_a?(String)
      file, warn_failure = load_logger(File.absolute_path(File.expand_path(file)), options)
    end

    finalize_create_logger(file, orig_file, warn_failure)
  end

  # :nodoc:
  def load_logger(file, options)
    warn_failure = false

    begin
      FileUtils.mkdir_p(File.dirname(file))
      @logger = Bovem::Logger.create(file, level: ::Logger::INFO)
    rescue
      options["log_file"] = "STDOUT"
      file = $stdout
      warn_failure = true
    end

    [file, warn_failure]
  end

  # :nodoc:
  def finalize_create_logger(file, orig_file, warn_failure)
    @logger = Bovem::Logger.create(file, level: ::Logger::INFO)
    @logger.warn(replace_markers(i18n.logging_failed(orig_file))) if @logger && warn_failure
    @logger
  end

  # :nodoc:
  def read_configuration(options)
    path = ::File.absolute_path(File.expand_path(options["configuration"]))

    begin
      @config = DevDNSd::Configuration.new(path, options, @logger)
      ensure_directory_for(@config.log_file) if @config.log_file.is_a?(String)
      ensure_directory_for(@config.pid_file)
      @logger = logger(true)
    rescue Bovem::Errors::InvalidConfiguration => e
      log_failed_configuration(path, e)
      shutdown
    end
  end

  # :nodoc:
  def ensure_directory_for(path)
    FileUtils.mkdir_p(File.dirname(path))
  rescue
    @logger.warn(replace_markers(i18n.invalid_directory(File.dirname(path))))
    shutdown
    Kernel.exit(1)
  end

  # :nodoc:
  def log_failed_configuration(path, exception)
    logger = Bovem::Logger.create($stderr)
    logger.fatal(exception.message)
    logger.warn(replace_markers(i18n.application_create_config(path)))
  end
end

Class Method Details

.check_ruby_implementationObject

Check if the current implementation supports DevDNSd.



119
120
121
122
123
124
# File 'lib/devdnsd/application.rb', line 119

def self.check_ruby_implementation
  if defined?(JRuby)
    Kernel.puts(Bovem::I18n.new(root: "devdnsd", path: ::Pathname.new(::File.dirname(__FILE__)).to_s + "/../../locales/").no_jruby)
    Kernel.exit(0)
  end
end

.instance(command = nil, locale = nil, force = false) ⇒ Application

Returns a unique (singleton) instance of the application.

Parameters:

  • command (Bovem::Command) (defaults to: nil)

    The current Bovem command.

  • locale (Symbol) (defaults to: nil)

    The locale to use for the application.

  • force (Boolean) (defaults to: false)

    If to force recreation of the instance.

Returns:

  • (Application)

    The unique (singleton) instance of the application.



98
99
100
101
102
# File 'lib/devdnsd/application.rb', line 98

def self.instance(command = nil, locale = nil, force = false)
  @instance = nil if force
  @instance ||= DevDNSd::Application.new(command, locale) if command
  @instance
end

.quitObject

Stops the application.



112
113
114
115
116
# File 'lib/devdnsd/application.rb', line 112

def self.quit
  instance.shutdown
rescue
  Kernel.exit(1)
end

.runObject

Runs the application in foreground.



107
108
109
# File 'lib/devdnsd/application.rb', line 107

def self.run
  instance.perform_server
end

Instance Method Details

#on_startNilClass

This method is called when the server starts. By default is a no-op.

Returns:

  • (NilClass)

    nil.



83
84
# File 'lib/devdnsd/application.rb', line 83

def on_start
end

#on_stopNilClass

This method is called when the server stop.

Returns:

  • (NilClass)

    nil.



89
90
# File 'lib/devdnsd/application.rb', line 89

def on_stop
end

#shutdownObject

Stops the server.



67
68
69
# File 'lib/devdnsd/application.rb', line 67

def shutdown
  server.actors.first.links.each(&:terminate) if server
end