Class: Sunshine::Daemon
- Inherits:
-
Object
- Object
- Sunshine::Daemon
- Defined in:
- lib/sunshine/daemon.rb
Overview
An abstract class to wrap simple daemon software setup and start/stop.
Child classes are expected to at least provide a start and stop bash script by either overloading the start_cmd and stop_cmd methods, or by setting may also be specified if restart requires more functionality than simply calling start_cmd && stop_cmd.
Direct Known Subclasses
Instance Attribute Summary collapse
-
#app ⇒ Object
readonly
Returns the value of attribute app.
-
#bin ⇒ Object
Returns the value of attribute bin.
-
#config_file ⇒ Object
Returns the value of attribute config_file.
-
#config_path ⇒ Object
Returns the value of attribute config_path.
-
#config_template ⇒ Object
Returns the value of attribute config_template.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#pid ⇒ Object
Returns the value of attribute pid.
-
#processes ⇒ Object
Returns the value of attribute processes.
-
#restart_cmd ⇒ Object
Gets the command that restarts the daemon.
-
#server_apps ⇒ Object
Returns the value of attribute server_apps.
-
#start_cmd ⇒ Object
Gets the command that starts the daemon.
-
#status_cmd ⇒ Object
Get the command to check if the daemon is running.
-
#stop_cmd ⇒ Object
Gets the command that stops the daemon.
-
#sudo ⇒ Object
Returns the value of attribute sudo.
-
#target ⇒ Object
readonly
Returns the value of attribute target.
-
#timeout ⇒ Object
Returns the value of attribute timeout.
Class Method Summary collapse
-
.binder_methods ⇒ Object
Returns an array of method names to assign to the binder for template rendering.
-
.underscore(str) ⇒ Object
Turn camelcase into underscore.
Instance Method Summary collapse
-
#config_file_path ⇒ Object
Get the file path to the daemon’s config file.
-
#config_template_files ⇒ Object
Get the array of local config template files needed by the daemon.
-
#each_server_app(&block) ⇒ Object
Do something with each server app used by the daemon.
-
#has_setup?(force = false) ⇒ Boolean
Check if setup was run successfully.
-
#initialize(app, options = {}) ⇒ Daemon
constructor
Daemon objects need only an App object to be instantiated but many options are available for customization:.
-
#log_file(key) ⇒ Object
Get the path of a log file: daemon.log_file(:stderr) #=> “/all_logs/stderr.log”.
-
#log_files(hash) ⇒ Object
Append or override daemon log file paths: daemon.log_files :stderr => “/all_logs/stderr.log”.
-
#restart ⇒ Object
Restarts the daemon using the restart_cmd attribute if provided.
-
#setup ⇒ Object
Setup the daemon, parse and upload config templates.
-
#start ⇒ Object
Start the daemon app after running setup.
-
#stop ⇒ Object
Stop the daemon app.
-
#upload_config_files(shell, setup_binding = binding) ⇒ Object
Upload config files and run them through erb with the provided binding if necessary.
Constructor Details
#initialize(app, options = {}) ⇒ Daemon
Daemon objects need only an App object to be instantiated but many options are available for customization:
- :pid
-
pid_path - set the pid; default: app.shared_path/pids/svr_name.pid
defaults to app.shared_path/pids/svr_name.pid - :bin
-
bin_path - set the daemon app bin path (e.g. usr/local/nginx)
defaults to svr_name - :sudo
-
bool|str - define if sudo should be used and with what user
- :timeout
-
int|str - timeout to use for daemon config
defaults to 1 - :processes
-
prcss_num - number of processes daemon should run
defaults to 0 - :config_template
-
path - glob path to tempates to render and upload
defaults to sunshine_path/templates/svr_name/* - :config_path
-
path - remote path daemon configs will be uploaded to
defaults to app.current_path/daemons/svr_name - :config_file
-
name - remote file name the daemon should load
defaults to svr_name.conf - :log_path
-
path - path to where the log files should be output
defaults to app.log_path - :point_to
-
app|daemon - an abstract target to point to
defaults to the passed app
The Daemon constructor also supports any App#find options to narrow the server apps to use. Note: subclasses such as Server already have a default :role that can be overridden.
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 |
# File 'lib/sunshine/daemon.rb', line 79 def initialize app, ={} @options = @app = app @target = [:point_to] || @app @short_class_name = self.class.underscore self.class.to_s.split("::").last @name = [:name] || @short_class_name @pid = [:pid] || "#{@app.shared_path}/pids/#{@name}.pid" @bin = [:bin] || @name @sudo = [:sudo] @timeout = [:timeout] || 0 @dep_name = [:dep_name] || @name @processes = [:processes] || 1 @config_template = [:config_template] @config_template ||= "#{Sunshine::ROOT}/templates/#{@short_class_name}/*" @config_path = [:config_path] || "#{@app.current_path}/daemons/#{@name}" @config_file = [:config_file] || "#{@name}.conf" log_path = [:log_path] || @app.log_path @log_files = { :stderr => "#{log_path}/#{@name}_stderr.log", :stdout => "#{log_path}/#{@name}_stdout.log" } @start_cmd = @stop_cmd = @restart_cmd = @status_cmd = nil @setup_successful = nil register_after_user_script end |
Instance Attribute Details
#app ⇒ Object (readonly)
Returns the value of attribute app.
34 35 36 |
# File 'lib/sunshine/daemon.rb', line 34 def app @app end |
#bin ⇒ Object
Returns the value of attribute bin.
36 37 38 |
# File 'lib/sunshine/daemon.rb', line 36 def bin @bin end |
#config_file ⇒ Object
Returns the value of attribute config_file.
38 39 40 |
# File 'lib/sunshine/daemon.rb', line 38 def config_file @config_file end |
#config_path ⇒ Object
Returns the value of attribute config_path.
38 39 40 |
# File 'lib/sunshine/daemon.rb', line 38 def config_path @config_path end |
#config_template ⇒ Object
Returns the value of attribute config_template.
38 39 40 |
# File 'lib/sunshine/daemon.rb', line 38 def config_template @config_template end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
34 35 36 |
# File 'lib/sunshine/daemon.rb', line 34 def name @name end |
#pid ⇒ Object
Returns the value of attribute pid.
36 37 38 |
# File 'lib/sunshine/daemon.rb', line 36 def pid @pid end |
#processes ⇒ Object
Returns the value of attribute processes.
36 37 38 |
# File 'lib/sunshine/daemon.rb', line 36 def processes @processes end |
#restart_cmd ⇒ Object
Gets the command that restarts the daemon.
263 264 265 |
# File 'lib/sunshine/daemon.rb', line 263 def restart_cmd @restart_cmd || [stop_cmd, start_cmd].map{|c| "(#{c})"}.join(" && ") end |
#server_apps ⇒ Object
Returns the value of attribute server_apps.
36 37 38 |
# File 'lib/sunshine/daemon.rb', line 36 def server_apps @server_apps end |
#start_cmd ⇒ Object
Gets the command that starts the daemon. Should be overridden by child classes.
244 245 246 247 |
# File 'lib/sunshine/daemon.rb', line 244 def start_cmd return @start_cmd || raise(CriticalDeployError, "@start_cmd undefined. Can't start #{@name}") end |
#status_cmd ⇒ Object
Get the command to check if the daemon is running.
271 272 273 |
# File 'lib/sunshine/daemon.rb', line 271 def status_cmd @status_cmd || "test -f #{@pid}" end |
#stop_cmd ⇒ Object
Gets the command that stops the daemon. Should be overridden by child classes.
254 255 256 257 |
# File 'lib/sunshine/daemon.rb', line 254 def stop_cmd return @stop_cmd || raise(CriticalDeployError, "@stop_cmd undefined. Can't stop #{@name}") end |
#sudo ⇒ Object
Returns the value of attribute sudo.
36 37 38 |
# File 'lib/sunshine/daemon.rb', line 36 def sudo @sudo end |
#target ⇒ Object (readonly)
Returns the value of attribute target.
34 35 36 |
# File 'lib/sunshine/daemon.rb', line 34 def target @target end |
#timeout ⇒ Object
Returns the value of attribute timeout.
36 37 38 |
# File 'lib/sunshine/daemon.rb', line 36 def timeout @timeout end |
Class Method Details
.binder_methods ⇒ Object
Returns an array of method names to assign to the binder for template rendering.
19 20 21 22 |
# File 'lib/sunshine/daemon.rb', line 19 def self.binder_methods [:app, :name, :target, :bin, :pid, :port, :processes, :config_path, :log_file, :timeout] end |
.underscore(str) ⇒ Object
Turn camelcase into underscore. Used for Daemon#name.
28 29 30 31 |
# File 'lib/sunshine/daemon.rb', line 28 def self.underscore str str.gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). gsub(/([a-z\d])([A-Z])/,'\1_\2').downcase end |
Instance Method Details
#config_file_path ⇒ Object
Get the file path to the daemon’s config file.
298 299 300 |
# File 'lib/sunshine/daemon.rb', line 298 def config_file_path "#{@config_path}/#{@config_file}" end |
#config_template_files ⇒ Object
Get the array of local config template files needed by the daemon.
325 326 327 |
# File 'lib/sunshine/daemon.rb', line 325 def config_template_files @config_template_files ||= Dir[@config_template].select{|f| File.file?(f)} end |
#each_server_app(&block) ⇒ Object
Do something with each server app used by the daemon.
120 121 122 |
# File 'lib/sunshine/daemon.rb', line 120 def each_server_app(&block) @app.each(@options, &block) end |
#has_setup?(force = false) ⇒ Boolean
Check if setup was run successfully.
163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/sunshine/daemon.rb', line 163 def has_setup? force=false return @setup_successful unless @setup_successful.nil? || force each_server_app do |server_app| unless server_app.shell.file? config_file_path return @setup_successful = false end end @setup_successful = true end |
#log_file(key) ⇒ Object
Get the path of a log file:
daemon.log_file(:stderr)
#=> "/all_logs/stderr.log"
290 291 292 |
# File 'lib/sunshine/daemon.rb', line 290 def log_file(key) @log_files[key] end |
#log_files(hash) ⇒ Object
Append or override daemon log file paths:
daemon.log_files :stderr => "/all_logs/stderr.log"
280 281 282 |
# File 'lib/sunshine/daemon.rb', line 280 def log_files(hash) @log_files.merge!(hash) end |
#restart ⇒ Object
Restarts the daemon using the restart_cmd attribute if provided. If restart_cmd is not provided, calls stop and start.
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 |
# File 'lib/sunshine/daemon.rb', line 222 def restart self.setup unless has_setup? Sunshine.logger.info @name, "Restarting #{@name} daemon" do each_server_app do |server_app| begin server_app.shell.call restart_cmd, :sudo => pick_sudo(server_app.shell) yield(server_app) if block_given? rescue => e raise CriticalDeployError.new(e, "Could not restart #{@name}") end end end end |
#setup ⇒ Object
Setup the daemon, parse and upload config templates. If a dependency with the daemon name exists in Sunshine.dependencies, setup will attempt to install the dependency before uploading configs. If a block is given it will be passed each server_app and binder object which will be used for the building erb config templates. See the ConfigBinding class for more information.
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 |
# File 'lib/sunshine/daemon.rb', line 133 def setup Sunshine.logger.info @name, "Setting up #{@name} daemon" do each_server_app do |server_app| # Build erb binding binder = config_binding server_app.shell server_app.shell.call "mkdir -p #{remote_dirs.join(" ")}", :sudo => binder.sudo yield(server_app, binder) if block_given? server_app.install_deps @dep_name if Sunshine.dependencies.exist?(@dep_name) upload_config_files(server_app.shell, binder.get_binding) end end @setup_successful = true rescue => e raise CriticalDeployError.new(e, "Could not setup #{@name}") end |
#start ⇒ Object
Start the daemon app after running setup.
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/sunshine/daemon.rb', line 180 def start self.setup unless has_setup? Sunshine.logger.info @name, "Starting #{@name} daemon" do each_server_app do |server_app| begin server_app.shell.call start_cmd, :sudo => pick_sudo(server_app.shell) yield(server_app) if block_given? rescue => e raise CriticalDeployError.new(e, "Could not start #{@name}") end end end end |
#stop ⇒ Object
Stop the daemon app.
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/sunshine/daemon.rb', line 201 def stop Sunshine.logger.info @name, "Stopping #{@name} daemon" do each_server_app do |server_app| begin server_app.shell.call stop_cmd, :sudo => pick_sudo(server_app.shell) yield(server_app) if block_given? rescue => e raise CriticalDeployError.new(e, "Could not stop #{@name}") end end end end |
#upload_config_files(shell, setup_binding = binding) ⇒ Object
Upload config files and run them through erb with the provided binding if necessary.
307 308 309 310 311 312 313 314 315 316 317 318 319 |
# File 'lib/sunshine/daemon.rb', line 307 def upload_config_files(shell, setup_binding=binding) config_template_files.each do |config_file| if File.extname(config_file) == ".erb" filename = File.basename(config_file[0..-5]) parsed_config = @app.build_erb(config_file, setup_binding) shell.make_file "#{@config_path}/#{filename}", parsed_config else filename = File.basename(config_file) shell.upload config_file, "#{@config_path}/#{filename}" end end end |