7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
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
115
116
|
# File 'lib/app-rb/command.rb', line 7
def deploy(target)
@base = "#{@config.app}-#{Time.now.to_i}"
start_at = Time.now
user = AppRb::Util.just_cmd("git config user.name")
current_hash = AppRb::Util::Consul.kv_get(@config.consul, @config.app, "hash")
build_nodes = @config.nodes(@config.image["constraint"])
if build_nodes.empty?
puts "FATAL ERROR: no build nodes found"
exit -1
end
pre_payloads = @config.pre_deploy.map do |pre|
payload = {
"nodes" => @config.nodes(pre["constraint"]),
"cmd" => pre["cmd"],
"opts" => pre["opts"] || [],
}
if payload["nodes"].empty?
puts "FATAL ERROR: no pre deploy nodes found"
exit -1
end
payload
end
deploy_payloads = @config.deploy.map { |key, section|
nodes = @config.nodes(section["constraint"])
if nodes.empty?
puts "FATAL ERROR: no deploy `#{key}` nodes found"
exit -1
end
{
"key" => key,
"nodes" => nodes,
"amount" => (section["per"] ? section["per"]*nodes.count : section["amount"]),
"cmd" => section["cmd"],
"port" => section["port"],
"check_url" => section["check_url"],
"opts" => section["opts"] || [],
}
}
if @config.run["constraint"]
run_nodes = @config.nodes(@config.run["constraint"])
else
run_nodes = deploy_payloads.flat_map { |payload| payload["nodes"] }.uniq
end
if run_nodes.empty?
puts "FATAL ERROR: no run nodes found"
exit -1
end
cron_payloads = @config.cron.map { |key, section|
nodes = @config.nodes(section["constraint"])
if nodes.empty?
puts "FATAL ERROR: no cron `#{key}` nodes found"
exit -1
end
{
"key" => key,
"nodes" => nodes,
"cmd" => section["cmd"],
"at" => "#{section["minute"] || "*"} #{section["hour"] || "*"} #{section["day"] || "*"} #{section["month"] || "*"} #{section["weekday"] || "*"}"
}
}
old_ips = AppRb::Util::Consul.kv_get(@config.consul, @config.app, "nodes").split(",")
new_ips = (
build_nodes.map(&:ip) +
pre_payloads.flat_map { |p| p["nodes"].map(&:ip) } +
deploy_payloads.flat_map { |p| p["nodes"].map(&:ip) } +
run_nodes.map(&:ip) +
cron_payloads.flat_map { |p| p["nodes"].map(&:ip) }
).uniq
ips = (old_ips + new_ips).uniq
AppRb::Util::Consul.kv_set(@config.consul, @config.app, "nodes", ips.join(","))
new_hash = prepare_image(build_nodes, target)
if @config.slack?
notify_slack(@config.slack_url, @config.slack_channel, "#{user} start deploy *#{@config.app}* - https://github.com/#{@config.image["repo"]}/compare/#{current_hash.to_s[0..6]}...#{new_hash.to_s[0..6]}")
end
pre_deploy(pre_payloads, new_hash)
stop_bg_jobs(ips)
do_deploy(deploy_payloads, new_hash)
blue_green(deploy_payloads, new_hash)
one_time_scripts(run_nodes, ips, new_hash)
set_crons(cron_payloads, ips, new_hash)
stop_services(ips)
clean_registry(current_hash, [current_hash, new_hash].uniq)
remove_old_images(ips, [current_hash, new_hash].uniq)
AppRb::Util::Consul.kv_set(@config.consul, @config.app, "nodes", new_ips.join(","))
if @config.slack?
notify_slack(@config.slack_url, @config.slack_channel, "#{user} finish deploy *#{@config.app}* :cat: :cat: :cat: - #{((Time.now.to_f - start_at.to_f)/60).round(1)} minutes")
end
puts AppRb::Util.green("Done.")
if current_hash != "" && !target && current_hash != target
puts "to rollback fire: app-rb #{ARGV[0]} deploy #{current_hash}"
end
end
|