smartguard 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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: []