Class: Chap::Runner

Inherits:
Object
  • Object
show all
Includes:
SpecialMethods
Defined in:
lib/chap/runner.rb

Constant Summary

Constants included from SpecialMethods

SpecialMethods::SPECIAL_METHODS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SpecialMethods

included

Constructor Details

#initialize(options = {}) ⇒ Runner

Returns a new instance of Runner.



6
7
8
9
# File 'lib/chap/runner.rb', line 6

def initialize(options={})
  @options = options
  @config = Config.new(options)
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



5
6
7
# File 'lib/chap/runner.rb', line 5

def config
  @config
end

#optionsObject (readonly)

Returns the value of attribute options.



5
6
7
# File 'lib/chap/runner.rb', line 5

def options
  @options
end

Instance Method Details

#camel_case(string) ⇒ Object



61
62
63
64
# File 'lib/chap/runner.rb', line 61

def camel_case(string)
  return string if string !~ /_/ && string =~ /[A-Z]+.*/
  string.split('_').map{|e| e.capitalize}.join
end

#cleanupObject



100
101
102
103
104
# File 'lib/chap/runner.rb', line 100

def cleanup
  log "Cleaning up".colorize(:green)
  remove_old_releases
  logrotate
end

#deployObject



11
12
13
14
# File 'lib/chap/runner.rb', line 11

def deploy
  deploy_to_symlink
  deploy_from_symlink
end


24
25
26
27
28
29
# File 'lib/chap/runner.rb', line 24

def deploy_from_symlink(use_previous=false)
  use_previous_timestamp if use_previous
  symlink_current
  hook(:restart)
  cleanup
end


16
17
18
19
20
21
22
# File 'lib/chap/runner.rb', line 16

def deploy_to_symlink
  setup
  strategy.deploy
  symlink_shared
  rm_rvmrc
  hook(:deploy)
end

#hook(name) ⇒ Object



155
156
157
158
159
160
161
162
163
# File 'lib/chap/runner.rb', line 155

def hook(name)
  log "Running hook: #{name}".colorize(:green)
  path = "#{release_path}/chap/#{name}"
  if File.exist?(path)
    Hook.new(path, @config).evaluate
  else
    log "chap/#{name} hook does not exist".colorize(:red)
  end
end

#logrotateObject



116
117
118
# File 'lib/chap/runner.rb', line 116

def logrotate
  logrotate_file(config.chap_log_path)
end

#logrotate_file(log_path) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
# File 'lib/chap/runner.rb', line 124

def logrotate_file(log_path)
  dirname = File.dirname(log_path)
  basename = File.basename(log_path, '.log')
  archive = "#{dirname}/#{basename}-#{logrotate_timestamp}.log"
  FileUtils.cp(log_path, archive) if File.exist?(log_path)
  logs = Dir.glob("#{dirname}/#{basename}-*.log").sort.reverse
  delete = logs - logs[0..9] # keep last 10 chap logs
  delete.each do |old_log|
    FileUtils.rm_f(old_log)
  end
end

#logrotate_timestampObject



120
121
122
# File 'lib/chap/runner.rb', line 120

def logrotate_timestamp
  @logrotate_timestamp ||= Time.now.strftime("%Y-%m-%d-%H-%M-%S")
end

#remove_old_releasesObject



106
107
108
109
110
111
112
113
114
# File 'lib/chap/runner.rb', line 106

def remove_old_releases
  dirname = File.dirname(release_path)
  releases = Dir.glob("#{dirname}/*").sort.reverse
  keep = config.chap[:keep] || 5
  delete = releases - releases[0..keep-1]
  delete.each do |old_release|
    FileUtils.rm_rf(old_release)
  end
end

#rm_rvmrcObject



93
94
95
96
97
98
# File 'lib/chap/runner.rb', line 93

def rm_rvmrc
  %w[.rvmrc .ruby-version].each do |file|
    path = "#{release_path}/#{file}"
    run "rm -f #{path}" if File.exist?(path)
  end
end

#setupObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/chap/runner.rb', line 36

def setup
  user = config.chap[:user] || ENV['USER']
  group = config.chap[:group]
  begin
    FileUtils.mkdir_p(deploy_to)
    FileUtils.chown_R user, group, deploy_to
  rescue Exception
    # retry to create deploy_to folder with sudo
    user_group = [user,group].compact.join(':')
    raise unless system("sudo mkdir -p #{deploy_to}")
    raise unless system("sudo chown -R #{user_group} #{deploy_to}")
  end
  dirs = ["#{deploy_to}/releases"]
  dirs += shared_dirs
  dirs.each do |dir|
    FileUtils.mkdir_p(dir)
  end
end

#shared_dirsObject



136
137
138
139
140
141
142
143
# File 'lib/chap/runner.rb', line 136

def shared_dirs
  dirs = config.chap[:shared_dirs] || [
    "system",
    "log",
    "tmp/pids"
  ]
  dirs.map! {|p| "#{shared_path}/#{p}"}
end

#strategyObject



55
56
57
58
59
# File 'lib/chap/runner.rb', line 55

def strategy
  strategy = config.strategy
  klass = Strategy.const_get(camel_case(strategy))
  @strategy ||= klass.new(:config => @config)
end


31
32
33
34
# File 'lib/chap/runner.rb', line 31

def symlink
  use_previous_timestamp
  symlink_current
end


87
88
89
90
91
# File 'lib/chap/runner.rb', line 87

def symlink_current
  FileUtils.rm(current_path) if File.exist?(current_path)
  FileUtils.ln_s(release_path, current_path)
  log "Current symlink updated".colorize(:green)
end


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/chap/runner.rb', line 66

def symlink_shared
  shared_dirs.each do |path|
    src = path
    relative_path = path.sub("#{shared_path}/",'')
    dest = if relative_path == "system"
             "#{release_path}/public/#{relative_path}"
           else
             "#{release_path}/#{relative_path}"
           end
    # make sure the directory exist for symlink creation
    dirname = File.dirname(dest)
    FileUtils.mkdir_p(dirname) unless File.exist?(dirname)
    if File.symlink?(dest)
      File.delete(dest)
    elsif File.exist?(dest)
      FileUtils.rm_rf(dest)
    end
    FileUtils.ln_s(src,dest)
  end
end

#test_hook(name) ⇒ Object



145
146
147
148
# File 'lib/chap/runner.rb', line 145

def test_hook(name)
  use_previous_timestamp
  hook(name)
end

#use_previous_timestampObject



150
151
152
153
# File 'lib/chap/runner.rb', line 150

def use_previous_timestamp
  timestamp = File.basename(latest_release)
  config.override_timestamp(timestamp)
end