smartguard 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/smartguard ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'smartguard'
4
+ require 'trollop'
5
+
6
+ opts = Trollop::options do
7
+ opt :application, "Application to use", :type => :string
8
+ opt :path, "Path to application", :type => :string
9
+ opt :port, "Port to run DRB", :type => :integer, :default => 10000
10
+ end
11
+
12
+ raise "You should specify application (--application)" if opts[:application].blank?
13
+ raise "You should specify application path (--path)" if opts[:path].blank?
14
+
15
+ application = Smartguard::Applications.const_get(opts[:application].camelize) rescue nil
16
+
17
+ raise "Application `#{opts[:application]}` not supported" if application.nil?
18
+
19
+ application = application.new(opts[:path])
20
+ application.warm_up
21
+
22
+ DRb.start_service("druby://localhost:#{opts[:port]}", application)
23
+ DRb.thread.join
@@ -0,0 +1,11 @@
1
+ module Smartguard
2
+ class Application
3
+ def initialize(path)
4
+ @base_path = Pathname.new(File.absolute_path path)
5
+ @current_path = @base_path.join('current')
6
+ @releases_path = @base_path.join('releases')
7
+ @shared_path = @base_path.join('shared')
8
+ @active_path = File.readlink @current_path
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ module Smartguard
2
+ module Applications
3
+ class Smartkiosk
4
+ class Cronic < Smartguard::Process
5
+ def initialize(path)
6
+ @path = path
7
+ @pid_file = path.join('tmp/pids/cronic.pid')
8
+ @log_file = path.join('log/cronic.log')
9
+ end
10
+
11
+ def pid
12
+ File.read(@pid_file).to_i rescue nil
13
+ end
14
+
15
+ def start
16
+ Logging.logger.info "Starting cronic"
17
+ run @path, "script/cronic -d -l #{@log_file} -P #{@pid_file} RAILS_ENV=production"
18
+ end
19
+
20
+ def stop
21
+ Logging.logger.info "Stoping cronic"
22
+ run @path, "script/cronic -k -P #{@pid_file}"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ module Smartguard
2
+ module Applications
3
+ class Smartkiosk
4
+ class Sidekiq < Smartguard::Process
5
+ def initialize(path)
6
+ @path = path
7
+ @config_path = path.join('config/sidekiq.yml')
8
+ @log_path = path.join('log/sidekiq_log')
9
+ @config = YAML.load_file(@config_path) rescue {}
10
+ end
11
+
12
+ def pid
13
+ File.read(@path.join @config[:pidfile]).to_i rescue nil
14
+ end
15
+
16
+ def start
17
+ Logging.logger.info "Starting sidekiq"
18
+
19
+ if @config[:pidfile].blank?
20
+ Logging.logger.warn "Sidekiq's config was not found"
21
+ return false
22
+ end
23
+
24
+ run @path, "bundle exec sidekiq -e production --config #{@config_path} >> #{@log_path} 2>&1 &"
25
+ end
26
+
27
+ def stop
28
+ Logging.logger.info "Stoping sidekiq"
29
+ run @path, "bundle exec sidekiqctl stop #{@config[:pidfile]} 60"
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,27 @@
1
+ module Smartguard
2
+ module Applications
3
+ class Smartkiosk
4
+ class Smartware < Smartguard::Process
5
+ def initialize(path)
6
+ @path = path
7
+ @pids_path = path.join('tmp/pids')
8
+ @logs_path = path.join('log')
9
+ end
10
+
11
+ def pid
12
+ File.read("#{@pids_path}/smartware.pid").to_i rescue nil
13
+ end
14
+
15
+ def start
16
+ Logging.logger.info "Starting smartware"
17
+ run @path, "bundle exec smartware piddir=#{@pids_path} logdir=#{@logs_path} &"
18
+ end
19
+
20
+ def stop
21
+ Logging.logger.info "Stoping smartware"
22
+ kill unless pid.blank?
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ module Smartguard
2
+ module Applications
3
+ class Smartkiosk
4
+ class Thin < Smartguard::Process
5
+ def initialize(path)
6
+ @path = path
7
+ @pid_file = path.join('tmp/pids/thin.pid')
8
+ end
9
+
10
+ def pid
11
+ File.read(@pid_file).to_i rescue nil
12
+ end
13
+
14
+ def start
15
+ Logging.logger.info "Starting thin"
16
+ run @path, "thin -d -e production start"
17
+ end
18
+
19
+ def stop
20
+ Logging.logger.info "Stoping thin"
21
+ run(@path, "thin -d -e production stop") unless pid.blank?
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,132 @@
1
+ module Smartguard
2
+ module Applications
3
+ class Smartkiosk < Smartguard::Application
4
+ def initialize(*args)
5
+ super
6
+ @head_path = @base_path.join('head')
7
+ end
8
+
9
+ def services
10
+ [:sidekiq, :smartware, :cronic, :thin]
11
+ end
12
+
13
+ def status
14
+ data = {}
15
+
16
+ services.each do |s|
17
+ service = send(s)
18
+
19
+ data[s] = [service.pid, service.active?]
20
+ end
21
+
22
+ data
23
+ end
24
+
25
+ def warm_up
26
+ Logging.logger.info 'Warming up'
27
+
28
+ services.each do |s|
29
+ service = send(s)
30
+
31
+ if !service.active?
32
+ if !service.start
33
+ stop_services
34
+ puts "Could not be started: #{s}"
35
+ exit
36
+ end
37
+ else
38
+ Logging.logger.info "#{s} is already active: #{service.pid}"
39
+ end
40
+ end
41
+ end
42
+
43
+ def restart(path=nil)
44
+ stop_services(path)
45
+ start_services(path)
46
+ end
47
+
48
+ def restart_asyn(path=nil)
49
+ Thread.new{ self.restart(path) }
50
+ true
51
+ end
52
+
53
+ def switch_release(release)
54
+ release = release.is_a?(Symbol) ? @releases_path.join(release.to_s)
55
+ : @base_path.join(release)
56
+
57
+ raise "Release doesn't exist: #{release.to_s}" unless File.exist? release
58
+
59
+ FileUtils.cd(release) do
60
+ Logging.logger.info "Installing release gems"
61
+ `bundle install`
62
+
63
+ Logging.logger.info "Migrating database"
64
+ `bundle exec rake db:migrate --trace RAILS_ENV=production`
65
+
66
+ Logging.logger.info "Compiling assets"
67
+ `bundle exec rake assets:precompile --trace RAILS_ENV=production`
68
+ end
69
+
70
+ self.stop_services
71
+
72
+ Logging.logger.info "Switching symlink from `#{@active_path}` to `#{release}`"
73
+ File.delete @current_path if File.symlink? @current_path
74
+ FileUtils.ln_s(release, @current_path)
75
+
76
+ @active_path = release if self.start_services do
77
+ Logging.logger.warn "New release `#{release}` did not start!"
78
+ self.stop_services
79
+
80
+ Logging.logger.info "Switching symlink back to `#{@active_path}`"
81
+ File.delete @current_path
82
+ FileUtils.ln_s @active_path, @current_path
83
+
84
+ self.start_services
85
+ end
86
+ end
87
+
88
+ def switch_release_async(release)
89
+ Thread.new{ switch_release(release) }
90
+ true
91
+ end
92
+
93
+ def start_services(path=nil, &block)
94
+ services.each do |s|
95
+ if !send(s, path).start && block_given?
96
+ Logging.logger.debug "Startup of #{s} failed: running safety block"
97
+ yield
98
+ return false
99
+ end
100
+ end
101
+ end
102
+
103
+ def stop_services(path=nil)
104
+ services.each do |s|
105
+ send(s, path).stop
106
+ end
107
+ end
108
+
109
+ protected
110
+
111
+ def sidekiq(path=nil)
112
+ Sidekiq.new wrap_path(path)
113
+ end
114
+
115
+ def smartware(path=nil)
116
+ Smartware.new wrap_path(path)
117
+ end
118
+
119
+ def cronic(path=nil)
120
+ Cronic.new wrap_path(path)
121
+ end
122
+
123
+ def thin(path=nil)
124
+ Thin.new wrap_path(path)
125
+ end
126
+
127
+ def wrap_path(path)
128
+ path.blank? ? @current_path : Pathname.new(path)
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,12 @@
1
+ module Smartguard
2
+ class Client
3
+ def initialize(port=10000)
4
+ DRb.start_service
5
+ @instance = DRbObject.new_with_uri("druby://localhost:#{port}")
6
+ end
7
+
8
+ def method_missing(method, *args, &block)
9
+ @instance.send method, *args, &block
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,32 @@
1
+ require 'logger'
2
+
3
+ module Smartguard
4
+ module Logging
5
+
6
+ def self.logdir=(dir)
7
+ @logdir = dir
8
+ end
9
+
10
+ def self.logger
11
+ @logger ||= begin
12
+ log = Logger.new(STDOUT)
13
+ log.level = Logger::DEBUG
14
+ log.formatter = Logger::Formatter.new
15
+ log
16
+ end
17
+ end
18
+
19
+ def self.logger=(val)
20
+ @logger = (val ? val : Logger.new('/dev/null'))
21
+ end
22
+
23
+ def self.logfile=(val)
24
+ @logfile = val
25
+ end
26
+
27
+ def self.logfile
28
+ @logfile
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ module Smartguard
2
+ class Process
3
+ include DRb::DRbUndumped
4
+
5
+ def run(path, command)
6
+ result = false
7
+
8
+ Bundler.with_clean_env do
9
+ FileUtils.cd(path) do
10
+ result = Kernel.system command
11
+ end
12
+ end
13
+
14
+ result
15
+ end
16
+
17
+ def kill
18
+ run @path, "kill -9 #{pid}"
19
+ end
20
+
21
+ def active?
22
+ !!::Process.getpgid(pid) rescue false
23
+ end
24
+ end
25
+ end
@@ -1,3 +1,3 @@
1
1
  module Smartguard
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/smartguard.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |gem|
10
10
  gem.email = ["boris@roundlake.ru"]
11
11
  gem.description = %q{Smartguard is the Smartkiosk services control daemon}
12
12
  gem.summary = gem.description
13
- gem.homepage = ""
13
+ gem.homepage = "https://github.com/roundlake/smartguard"
14
14
 
15
15
  gem.files = `git ls-files`.split($/)
16
16
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smartguard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-12-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: i18n
16
- requirement: &70194555401080 !ruby/object:Gem::Requirement
16
+ requirement: &70236313873140 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70194555401080
24
+ version_requirements: *70236313873140
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: active_support
27
- requirement: &70194555400180 !ruby/object:Gem::Requirement
27
+ requirement: &70236313872100 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70194555400180
35
+ version_requirements: *70236313872100
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: trollop
38
- requirement: &70194555399460 !ruby/object:Gem::Requirement
38
+ requirement: &70236313871280 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70194555399460
46
+ version_requirements: *70236313871280
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: pry
49
- requirement: &70194555398800 !ruby/object:Gem::Requirement
49
+ requirement: &70236313870400 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,11 +54,12 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70194555398800
57
+ version_requirements: *70236313870400
58
58
  description: Smartguard is the Smartkiosk services control daemon
59
59
  email:
60
60
  - boris@roundlake.ru
61
- executables: []
61
+ executables:
62
+ - smartguard
62
63
  extensions: []
63
64
  extra_rdoc_files: []
64
65
  files:
@@ -67,10 +68,20 @@ files:
67
68
  - LICENSE.txt
68
69
  - README.md
69
70
  - Rakefile
71
+ - bin/smartguard
70
72
  - lib/smartguard.rb
73
+ - lib/smartguard/application.rb
74
+ - lib/smartguard/applications/smartkiosk.rb
75
+ - lib/smartguard/applications/smartkiosk/cronic.rb
76
+ - lib/smartguard/applications/smartkiosk/sidekiq.rb
77
+ - lib/smartguard/applications/smartkiosk/smartware.rb
78
+ - lib/smartguard/applications/smartkiosk/thin.rb
79
+ - lib/smartguard/client.rb
80
+ - lib/smartguard/logging.rb
81
+ - lib/smartguard/process.rb
71
82
  - lib/smartguard/version.rb
72
83
  - smartguard.gemspec
73
- homepage: ''
84
+ homepage: https://github.com/roundlake/smartguard
74
85
  licenses: []
75
86
  post_install_message:
76
87
  rdoc_options: []