ors 0.2.10 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/README.markdown +71 -0
  2. data/bin/ors +1 -1
  3. data/lib/ors.rb +21 -2
  4. data/lib/ors/base.rb +30 -0
  5. data/lib/ors/commands/base.rb +56 -12
  6. data/lib/ors/commands/changes.rb +21 -7
  7. data/lib/ors/commands/console.rb +16 -18
  8. data/lib/ors/commands/deploy.rb +24 -13
  9. data/lib/ors/commands/env.rb +9 -9
  10. data/lib/ors/commands/exec.rb +14 -7
  11. data/lib/ors/commands/help.rb +9 -11
  12. data/lib/ors/commands/logs.rb +16 -14
  13. data/lib/ors/commands/migrate.rb +8 -9
  14. data/lib/ors/commands/restart.rb +9 -11
  15. data/lib/ors/commands/ruby.rb +8 -6
  16. data/lib/ors/commands/runner.rb +29 -25
  17. data/lib/ors/commands/setup.rb +16 -16
  18. data/lib/ors/commands/start.rb +9 -11
  19. data/lib/ors/commands/stop.rb +9 -11
  20. data/lib/ors/commands/symlink.rb +31 -0
  21. data/lib/ors/commands/timestamps.rb +27 -0
  22. data/lib/ors/commands/update.rb +15 -11
  23. data/lib/ors/config.rb +88 -58
  24. data/lib/ors/helpers.rb +107 -76
  25. data/lib/ors/log_unifier.rb +2 -2
  26. data/lib/ors/version.rb +2 -2
  27. data/spec/ors/{command_spec.rb → base_spec.rb} +11 -8
  28. data/spec/ors/commands/base_spec.rb +17 -9
  29. data/spec/ors/commands/deploy_spec.rb +4 -3
  30. data/spec/ors/commands/runner_spec.rb +8 -27
  31. data/spec/ors/commands/timestamps_spec.rb +16 -0
  32. data/spec/ors/commands/update_spec.rb +8 -3
  33. data/spec/ors/config_spec.rb +56 -61
  34. data/spec/ors/helpers_spec.rb +6 -2
  35. data/spec/ors/log_unifier_spec.rb +2 -2
  36. metadata +82 -57
  37. data/README +0 -52
  38. data/lib/ors/command.rb +0 -46
  39. data/lib/ors/commands/check.rb +0 -27
  40. data/lib/ors/commands/sync.rb +0 -27
  41. data/lib/ors/core_ext.rb +0 -53
  42. data/spec/ors/commands/check_spec.rb +0 -15
@@ -1,13 +1,12 @@
1
- module ORS::Commands
1
+ class ORS
2
+ module Commands
3
+ class Migrate < Base
2
4
 
3
- class Migrate < Base
4
-
5
- def execute
6
- info "migrating #{name} #{environment}..."
7
-
8
- run_migrations migration_server
9
- end
5
+ def execute
6
+ info "migrating #{ORS.config[:name]} #{ORS.config[:environment]}..."
10
7
 
8
+ run_migrations ORS.config[:migration_server]
9
+ end
10
+ end # Migrate < Base
11
11
  end
12
-
13
12
  end
@@ -1,13 +1,11 @@
1
- module ORS::Commands
2
-
3
- class Restart < Base
4
-
5
- def execute
6
- info "restarting #{name} #{environment}..."
7
-
8
- execute_in_parallel(app_servers) {|server| restart_server server }
9
- end
10
-
1
+ class ORS
2
+ module Commands
3
+ class Restart < Base
4
+ def execute
5
+ info "restarting #{ORS.config[:name]} #{ORS.config[:environment]}..."
6
+
7
+ execute_in_parallel(ORS.config[:app_servers]) {|server| restart_server server }
8
+ end
9
+ end # Restart < Base
11
10
  end
12
-
13
11
  end
@@ -1,8 +1,10 @@
1
- module ORS::Commands
2
- class Ruby < Base
3
- def execute
4
- info "setting up ruby/rubygems for #{name} #{environment}..."
5
- execute_in_parallel(ruby_servers) {|server| setup_ruby server }
6
- end
1
+ class ORS
2
+ module Commands
3
+ class Ruby < Base
4
+ def execute
5
+ info "setting up ruby/rubygems for #{ORS.config[:name]} #{ORS.config[:environment]}..."
6
+ execute_in_parallel(ORS.config[:ruby_servers]) {|server| setup_ruby server }
7
+ end
8
+ end # Ruby < Base
7
9
  end
8
10
  end
@@ -1,33 +1,37 @@
1
- module ORS::Commands
2
- class Runner < Base
3
- def execute
4
- begin
5
- code = ORS::Config.options[ ORS::Config.options.index{|e| e =~ /^(-c|--code)$/} + 1 ]
6
- raise if code.strip.empty?
7
- rescue
8
- fatal "ERROR: Missing option --code 'ruby code'."
1
+ class ORS
2
+ module Commands
3
+ class Runner < Base
4
+ def setup
5
+ @code = ORS.config[:args].shift
9
6
  end
10
- results = execute_command console_server, prepare_environment,
11
- %(if [ -f script/rails ]; then bundle exec rails runner -e #{environment} \\"#{code}\\"; else ./script/runner -e #{environment} \\"#{code}\\"; fi),
12
- :capture => true, :quiet_ssh => true
13
- results.sub!(/\AUsing BufferedLogger due to exception: .*?\n/, '') # The central_logger gem spits this out without any way of shutting it up
14
- puts results
15
- end
16
7
 
17
- def help
18
- puts <<-END
19
- Usage: ./ors runner [environment=production] --code "ruby code here" [options]
8
+ def execute
9
+ # need code to run
10
+ fatal "ERROR: Missing 'ruby code'." if @code.nil?
20
11
 
21
- === Description
12
+ # get results
13
+ results = execute_command(ORS.config[:console_server],
14
+ prepare_environment,
15
+ %(if [ -f script/rails ]; then bundle exec rails runner -e #{ORS.config[:environment]} \\"#{@code}\\"; else ./script/runner -e #{ORS.config[:environment]} \\"#{@code}\\"; fi),
16
+ :capture => true, :quiet_ssh => true)
17
+
18
+ # The central_logger gem spits this out
19
+ results.sub!(/\AUsing BufferedLogger due to exception: .*?\n/, '')
20
+
21
+ puts results
22
+ end
23
+
24
+ def usage
25
+ "./ors runner 'ruby code here' [options]"
26
+ end
27
+
28
+ def description
29
+ <<-END
22
30
  Runs rails runner returning the result on STDOUT.
23
31
  The ruby code will be transmitted within several nested quotes: '"\"ruby code here\""'
24
32
  Keep that in mind if you need to use quotes.
25
-
26
- === Options
27
- --code (or -c) The code to run.
28
- --pretend (or -p) Don't execute anything, just show me what you're going to do
29
- --no-gateway (or -ng) Don't use a gateway (if you're inside the firewall)
30
- END
31
- end
33
+ END
34
+ end
35
+ end # Runner < Base
32
36
  end
33
37
  end
@@ -1,23 +1,23 @@
1
- module ORS::Commands
1
+ class ORS
2
+ module Commands
3
+ class Setup < Base
2
4
 
3
- class Setup < Base
5
+ def execute
6
+ info "setting up #{ORS.config[:name]} #{ORS.config[:environment]}..."
4
7
 
5
- def execute
6
- info "setting up #{name} #{environment}..."
8
+ info "Are you sure? ('yes' + ctrl+D^2)"
9
+ if ORS.config[:pretending] || STDIN.read == "yes"
10
+ execute_in_parallel(ORS.config[:all_servers]) {|server| setup_repo server }
7
11
 
8
- info "Are you sure? ('yes' + ctrl+D^2)"
9
- if pretending || STDIN.read == "yes"
10
- execute_in_parallel(all_servers) {|server| setup_repo server }
12
+ Ruby.run_without_setup
11
13
 
12
- run Ruby
13
-
14
- execute_command migration_server, prepare_environment,
15
- %(RAILS_ENV=#{environment} bundle exec rake db:create)
16
- else
17
- info "Setup aborted."
14
+ execute_command(ORS.config[:migration_server],
15
+ prepare_environment,
16
+ %(RAILS_ENV=#{environment} bundle exec rake db:create))
17
+ else
18
+ info "Setup aborted."
19
+ end
18
20
  end
19
- end
20
-
21
+ end # Setup < Base
21
22
  end
22
-
23
23
  end
@@ -1,13 +1,11 @@
1
- module ORS::Commands
2
-
3
- class Start < Base
4
-
5
- def execute
6
- info "starting #{name} #{environment}..."
7
-
8
- execute_in_parallel(app_servers) {|server| start_server server }
9
- end
10
-
1
+ class ORS
2
+ module Commands
3
+ class Start < Base
4
+ def execute
5
+ info "starting #{ORS.config[:name]} #{ORS.config[:environment]}..."
6
+
7
+ execute_in_parallel(ORS.config[:app_servers]) {|server| start_server server }
8
+ end
9
+ end # Start < Base
11
10
  end
12
-
13
11
  end
@@ -1,13 +1,11 @@
1
- module ORS::Commands
2
-
3
- class Stop < Base
4
-
5
- def execute
6
- info "stopping #{name} #{environment}..."
7
-
8
- execute_in_parallel(app_servers) {|server| stop_server server }
9
- end
10
-
1
+ class ORS
2
+ module Commands
3
+ class Stop < Base
4
+ def execute
5
+ info "stopping #{ORS.config[:name]} #{ORS.config[:environment]}..."
6
+
7
+ execute_in_parallel(ORS.config[:app_servers]) {|server| stop_server server }
8
+ end
9
+ end # Stop < Base
11
10
  end
12
-
13
11
  end
@@ -0,0 +1,31 @@
1
+ class ORS
2
+ module Commands
3
+ class Symlink < Base
4
+
5
+ def setup
6
+ parse_remote_and_or_branch
7
+ end
8
+
9
+ def execute
10
+ info "symlinking #{ORS.config[:name]} #{ORS.config[:environment]}..."
11
+
12
+ execute_in_parallel(ORS.config[:ruby_servers]) do |server|
13
+ info "[#{server}] symlinking..."
14
+ execute_command(server,
15
+ prepare_environment,
16
+ #%(if [ -d config/deploy ]; then cd config/deploy; for i in ./**/*; do if [ -f \\\$i ]; then echo \\\$i; fi; done; cd ../../; fi))
17
+ %(if [ -d config/deploy ]; then cd config/deploy; for i in ./**/*; do if [ -f \\\$i ]; then ln -nfs #{ORS.config[:deploy_directory]}/config/deploy/\\\$i ../../\\\$i; fi; done; cd ../../; fi))
18
+
19
+ end
20
+ end
21
+
22
+ def usage
23
+ "./ors symlink [remote|remote/branch] [options]"
24
+ end
25
+
26
+ def description
27
+ "Symlinks files in config/deploy/ in given branch (origin/environment by default) to given environment"
28
+ end
29
+ end # Deploy < Base
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ class ORS
2
+ module Commands
3
+
4
+ # ors timestamps
5
+ # ors timestamps from staging
6
+ class Timestamps < Base
7
+ def execute
8
+ timestamps = ORS.config[:app_servers].map do |server|
9
+ [
10
+ "[#{server}] ",
11
+ execute_command(server, prepare_environment, %(cat restart.timestamp), :capture => true)
12
+ ].join
13
+ end.join("\n")
14
+
15
+ puts timestamps unless ORS.config[:pretending]
16
+ end
17
+
18
+ def usage
19
+ "./ors check [options]"
20
+ end
21
+
22
+ def description
23
+ "Prints out contents of restart.timestamp on the app servers"
24
+ end
25
+ end # Timestamps < Base
26
+ end
27
+ end
@@ -1,17 +1,21 @@
1
- module ORS::Commands
1
+ class ORS
2
+ module Commands
3
+ class Update < Base
2
4
 
3
- class Update < Base
5
+ def setup
6
+ parse_remote_and_or_branch
7
+ end
4
8
 
5
- def execute
6
- info "updating #{name} #{environment}..."
9
+ def execute
10
+ info "updating #{ORS.config[:name]} #{ORS.config[:environment]}..."
7
11
 
8
- execute_in_parallel(all_servers) {|server| update_code server }
9
- execute_in_parallel(ruby_servers) {|server| bundle_install server }
10
-
11
- execute_command cron_server, prepare_environment,
12
- %(if [ -f config/schedule.rb ]; then bundle exec whenever --update-crontab --set environment=#{environment} -i #{name}_#{environment}; fi)
13
- end
12
+ execute_in_parallel(ORS.config[:all_servers]) {|server| update_code(server) }
13
+ execute_in_parallel(ORS.config[:ruby_servers]) {|server| bundle_install(server) }
14
14
 
15
+ execute_command(ORS.config[:cron_server],
16
+ prepare_environment,
17
+ %(if [ -f config/schedule.rb ]; then bundle exec whenever --update-crontab --set environment=#{ORS.config[:environment]} -i #{ORS.config[:name]}_#{ORS.config[:environment]}; fi))
18
+ end
19
+ end # Update < Base
15
20
  end
16
-
17
21
  end
data/lib/ors/config.rb CHANGED
@@ -1,90 +1,120 @@
1
- module ORS
2
- module Config
1
+ class ORS
2
+ class Config
3
3
 
4
- CONFIG_FILENAME="config/deploy.yml"
4
+ CONFIG_FILENAME = "config/deploy.yml"
5
5
 
6
- mattr_accessor :name, :environment, :use_gateway, :pretending, :log_lines, :rails2, :deploy_hook, :remote_deploy_hook
7
- mattr_accessor :gateway, :deploy_user, :repo, :base_path, :web_servers, :app_servers, :migration_server, :console_server, :cron_server
8
- mattr_accessor :options
6
+ @@args = []
7
+ @@options = {}
9
8
 
10
- self.environment = "production"
11
- self.pretending = false
12
- self.use_gateway = true
13
- self.log_lines = 100
9
+ def initialize(options)
10
+ parse_options(options)
11
+ parse_config_file
12
+ end
14
13
 
15
- module ModuleMethods
14
+ def _options
15
+ @@options
16
+ end
16
17
 
17
- def parse_options options
18
- self.name = name_from_git
19
- self.environment = options.shift unless options.empty? or options.first.match(/^-/)
20
- self.options = options.dup
18
+ def [](key)
19
+ @@options[key]
20
+ end
21
21
 
22
- options.each do |option|
23
- case option
24
- when "-p", "--pretend" then self.pretending = true
25
- when "-ng", "--no-gateway" then self.use_gateway = false
26
- end
27
- end
28
- end
22
+ def []=(key, value)
23
+ @@options[key] = value
24
+ end
29
25
 
30
- def parse_config_file
31
- if File.exists?(CONFIG_FILENAME)
32
- YAML.load(File.read(CONFIG_FILENAME)).each {|(name, value)| send "#{name}=", value }
33
- else
34
- self.gateway = "deploy-gateway"
35
- self.deploy_user = "deployer"
36
- self.repo = "ors_git"
37
- self.base_path = "/var/www"
38
- self.web_servers = %w(koala)
39
- self.app_servers = %w(eel jellyfish squid)
40
- self.migration_server = "tuna"
41
- self.console_server = "tuna"
42
- self.cron_server = "tuna"
43
- end
44
- end
26
+ def parse_options(options)
27
+ @@options[:pretending] = true if options.delete("-p") || options.delete("--pretend")
45
28
 
46
- def valid_options?
47
- name.to_s.size > 0 and valid_environments.include?(environment)
29
+ if options.delete("-ng") || options.delete("--no-gateway")
30
+ @@options[:use_gateway] = false
31
+ else
32
+ @@options[:use_gateway] = true
48
33
  end
49
34
 
50
- def valid_environments
51
- %w(production demo staging)
35
+ # grab environment
36
+ index = options.index("to") || options.index("from")
37
+ unless index.nil?
38
+ @@options[:environment] = options.delete_at(index + 1)
39
+ options.delete_at(index)
52
40
  end
53
41
 
54
- def git
55
- @git ||= Git.open(Dir.pwd)
56
- end
42
+ @@options[:args] = options.dup
57
43
 
58
- private
44
+ set_default_options
45
+ end
46
+
47
+ def set_default_options
48
+ @@options[:environment] ||= "production"
49
+ @@options[:remote] ||= "origin"
50
+ @@options[:branch] ||= @@options[:environment]
51
+ @@options[:pretending] ||= false
52
+ @@options[:log_lines] = 100
53
+
54
+ @@options[:gateway] = "deploy-gateway"
55
+ @@options[:user] = "deployer"
56
+ @@options[:base_path] = "/var/www"
57
+ @@options[:web_servers] = %w(koala)
58
+ @@options[:app_servers] = %w(eel jellyfish squid)
59
+ @@options[:migration_server] = "tuna"
60
+ @@options[:console_server] = "tuna"
61
+ @@options[:cron_server] = "tuna"
62
+ end
59
63
 
60
- def name_from_git
61
- git.config["remote.origin.url"].gsub(/^[\w]*(@|:\/\/)[^\/:]*(\/|:)([a-zA-Z0-9\/]*)(.git)?$/i, '\3')
64
+ def parse_config_file
65
+ if File.exists?(CONFIG_FILENAME)
66
+ YAML.load(File.read(CONFIG_FILENAME)).each do |(name, value)|
67
+ @@options[name.to_sym] = value
68
+ end
62
69
  end
70
+ end
71
+
72
+ def finalize!
73
+ @@options[:name] = name
74
+ @@options[:remote_url] = remote_url
75
+ @@options[:deploy_directory] = deploy_directory
76
+
77
+ @@options[:revision] = git.log(1).first.sha
78
+
79
+ @@options[:ruby_servers] = [@@options[:app_servers], @@options[:console_server], @@options[:cron_server], @@options[:migration_server]].flatten.compact.uniq
80
+ @@options[:all_servers] = [@@options[:web_servers], @@options[:ruby_servers]].flatten.compact.uniq
81
+ end
63
82
 
83
+ def git
84
+ @git ||= Git.open(Dir.pwd)
64
85
  end
65
- extend ModuleMethods
66
86
 
67
- def ruby_servers
68
- (app_servers + [console_server, cron_server, migration_server]).uniq
87
+ def valid?
88
+ name.to_s.size > 0
69
89
  end
70
90
 
71
- def all_servers
72
- (web_servers + ruby_servers).uniq
91
+
92
+ private
93
+
94
+ #
95
+ # methods to help finalize the config
96
+ #
97
+
98
+ def remote_url
99
+ if git.config.has_key?("remote.#{@@options[:remote]}.url")
100
+ git.config["remote.#{@@options[:remote]}.url"]
101
+ else
102
+ raise StandardError, "There is no #{@@options[:remote]} remote in your git config, please check your config/deploy.yml"
103
+ end
73
104
  end
74
105
 
75
- def revision
76
- Config.git.log(1).first.sha
106
+ def name
107
+ remote_url.gsub(/^[\w]*(@|:\/\/)[^\/:]*(\/|:)([a-zA-Z0-9\/_\-]*)(.git)?$/i, '\3')
77
108
  end
78
109
 
79
110
  def deploy_directory
80
- directory = File.join base_path, name
111
+ directory = File.join(@@options[:base_path], @@options[:name])
81
112
 
82
- if environment == "production"
113
+ if @@options[:environment] == "production"
83
114
  directory
84
115
  else
85
- "#{directory}_#{environment}"
116
+ "#{directory}_#{@@options[:environment]}"
86
117
  end
87
118
  end
88
-
89
119
  end
90
120
  end