caco 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +10 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +227 -0
- data/Guardfile +42 -0
- data/LICENSE.txt +21 -0
- data/README.md +97 -0
- data/Rakefile +10 -0
- data/bin/_guard-core +29 -0
- data/bin/bundle +114 -0
- data/bin/byebug +29 -0
- data/bin/caco +29 -0
- data/bin/coderay +29 -0
- data/bin/console +20 -0
- data/bin/eyaml +29 -0
- data/bin/guard +29 -0
- data/bin/listen +29 -0
- data/bin/pry +29 -0
- data/bin/rake +29 -0
- data/bin/safe_yaml +29 -0
- data/bin/setup +8 -0
- data/bin/thor +29 -0
- data/bin/tilt +29 -0
- data/caco.gemspec +43 -0
- data/exe/caco +27 -0
- data/lib/caco.rb +115 -0
- data/lib/caco/barman.rb +10 -0
- data/lib/caco/barman/cell/global.rb +4 -0
- data/lib/caco/barman/cell/node.rb +15 -0
- data/lib/caco/barman/install.rb +25 -0
- data/lib/caco/barman/view/global.erb +7 -0
- data/lib/caco/barman/view/node.erb +8 -0
- data/lib/caco/cell.rb +8 -0
- data/lib/caco/config.rb +23 -0
- data/lib/caco/debian.rb +28 -0
- data/lib/caco/debian/add_user.rb +18 -0
- data/lib/caco/debian/apt_key_install.rb +19 -0
- data/lib/caco/debian/apt_repo_add.rb +17 -0
- data/lib/caco/debian/apt_sources_list.rb +15 -0
- data/lib/caco/debian/apt_update.rb +33 -0
- data/lib/caco/debian/cell/service.rb +19 -0
- data/lib/caco/debian/cell/sources_list.rb +7 -0
- data/lib/caco/debian/package_install.rb +21 -0
- data/lib/caco/debian/package_installed.rb +17 -0
- data/lib/caco/debian/service_enable.rb +26 -0
- data/lib/caco/debian/service_install.rb +31 -0
- data/lib/caco/debian/user_home.rb +17 -0
- data/lib/caco/debian/view/service.erb +18 -0
- data/lib/caco/debian/view/sources_list.erb +10 -0
- data/lib/caco/downloader.rb +41 -0
- data/lib/caco/executer.rb +33 -0
- data/lib/caco/facter.rb +41 -0
- data/lib/caco/file_link.rb +36 -0
- data/lib/caco/file_reader.rb +24 -0
- data/lib/caco/file_writer.rb +57 -0
- data/lib/caco/finder.rb +13 -0
- data/lib/caco/grafana.rb +6 -0
- data/lib/caco/grafana/install.rb +26 -0
- data/lib/caco/haproxy.rb +12 -0
- data/lib/caco/haproxy/cell/conf_postgres.rb +4 -0
- data/lib/caco/haproxy/cell/conf_stats.rb +4 -0
- data/lib/caco/haproxy/conf_get.rb +15 -0
- data/lib/caco/haproxy/conf_set.rb +52 -0
- data/lib/caco/haproxy/install.rb +9 -0
- data/lib/caco/haproxy/view/conf_postgres.erb +25 -0
- data/lib/caco/haproxy/view/conf_stats.erb +6 -0
- data/lib/caco/macro.rb +2 -0
- data/lib/caco/postgres.rb +44 -0
- data/lib/caco/postgres/build_augeas.rb +20 -0
- data/lib/caco/postgres/conf_get.rb +37 -0
- data/lib/caco/postgres/conf_set.rb +54 -0
- data/lib/caco/postgres/database_create.rb +28 -0
- data/lib/caco/postgres/extension_create.rb +28 -0
- data/lib/caco/postgres/hba_set.rb +65 -0
- data/lib/caco/postgres/install.rb +34 -0
- data/lib/caco/postgres/shell.rb +13 -0
- data/lib/caco/postgres/sql.rb +17 -0
- data/lib/caco/postgres/user_change_password.rb +13 -0
- data/lib/caco/postgres/user_create.rb +33 -0
- data/lib/caco/prometheus.rb +15 -0
- data/lib/caco/prometheus/adapter_install_pg.rb +107 -0
- data/lib/caco/prometheus/adapter_install_postgresql.rb +47 -0
- data/lib/caco/prometheus/cell/alertmanager_conf.rb +4 -0
- data/lib/caco/prometheus/cell/alerts.rb +4 -0
- data/lib/caco/prometheus/cell/conf.rb +7 -0
- data/lib/caco/prometheus/exporter_install.rb +35 -0
- data/lib/caco/prometheus/install.rb +50 -0
- data/lib/caco/prometheus/install_alert_manager.rb +62 -0
- data/lib/caco/prometheus/view/alertmanager_conf.erb +13 -0
- data/lib/caco/prometheus/view/alerts.erb +18 -0
- data/lib/caco/prometheus/view/conf.erb +34 -0
- data/lib/caco/rbenv.rb +8 -0
- data/lib/caco/rbenv/cell/profile.rb +4 -0
- data/lib/caco/rbenv/install.rb +56 -0
- data/lib/caco/rbenv/install_version.rb +17 -0
- data/lib/caco/rbenv/view/profile.erb +3 -0
- data/lib/caco/repmgr.rb +15 -0
- data/lib/caco/repmgr/cell/conf.rb +43 -0
- data/lib/caco/repmgr/conf.rb +25 -0
- data/lib/caco/repmgr/install.rb +25 -0
- data/lib/caco/repmgr/node_register_primary.rb +34 -0
- data/lib/caco/repmgr/node_register_standby.rb +25 -0
- data/lib/caco/repmgr/node_registered.rb +15 -0
- data/lib/caco/repmgr/node_role.rb +18 -0
- data/lib/caco/repmgr/view/conf.erb +27 -0
- data/lib/caco/settings_loader.rb +67 -0
- data/lib/caco/settings_loader_monkeypatch.rb +28 -0
- data/lib/caco/ssh.rb +6 -0
- data/lib/caco/ssh/authorized_keys_add.rb +82 -0
- data/lib/caco/sudo.rb +6 -0
- data/lib/caco/sudo/sudoers_add.rb +15 -0
- data/lib/caco/timescale.rb +6 -0
- data/lib/caco/timescale/install.rb +25 -0
- data/lib/caco/unpacker.rb +76 -0
- data/lib/caco/version.rb +3 -0
- metadata +398 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
module Caco::Debian
|
2
|
+
class AptSourcesList < Trailblazer::Operation
|
3
|
+
step ->(ctx, mirror_url: nil, **) {
|
4
|
+
ctx[:content] = Caco::Debian::Cell::SourcesList.(mirror_url: mirror_url).to_s
|
5
|
+
},
|
6
|
+
id: :generate_content
|
7
|
+
|
8
|
+
step ->(ctx, **) { ctx[:path] = '/etc/apt/sources.list' },
|
9
|
+
id: :build_path
|
10
|
+
|
11
|
+
step Subprocess(Caco::FileWriter),
|
12
|
+
input: [:path, :content],
|
13
|
+
output: { file_changed: :sources_updated }
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Caco::Debian
|
2
|
+
class AptUpdate < Trailblazer::Operation
|
3
|
+
step :apt_needs_update,
|
4
|
+
Output(Trailblazer::Activity::Left, :failure) => End(:success)
|
5
|
+
|
6
|
+
step Subprocess(Caco::Executer),
|
7
|
+
input: ->(_ctx, **) {{
|
8
|
+
command: 'apt-get update'
|
9
|
+
}},
|
10
|
+
output: { exit_code: :command_exit_code, output: :command_output }
|
11
|
+
|
12
|
+
step :apt_updated
|
13
|
+
|
14
|
+
fail :command_failed
|
15
|
+
|
16
|
+
def apt_needs_update(ctx, force: false, **)
|
17
|
+
ctx[:apt_needs_update] = !Caco::Debian.apt_updated
|
18
|
+
ctx[:apt_needs_update] = true if force
|
19
|
+
ctx[:apt_needs_update]
|
20
|
+
end
|
21
|
+
|
22
|
+
def apt_updated(ctx, **)
|
23
|
+
ctx[:apt_updated] = true
|
24
|
+
Caco::Debian.apt_updated = true
|
25
|
+
end
|
26
|
+
|
27
|
+
def command_failed(ctx, command_exit_code:, command_output:, **)
|
28
|
+
ctx[:apt_updated] = false
|
29
|
+
Caco::Debian.apt_updated = false
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Caco::Debian::Cell
|
2
|
+
class Service < Trailblazer::Cell
|
3
|
+
def description
|
4
|
+
property(:description) || "No Description Provided"
|
5
|
+
end
|
6
|
+
|
7
|
+
def environment_file
|
8
|
+
property(:environment_file)
|
9
|
+
end
|
10
|
+
|
11
|
+
def environment_vars
|
12
|
+
property(:environment_vars) || []
|
13
|
+
end
|
14
|
+
|
15
|
+
def command
|
16
|
+
property(:command)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Caco::Debian
|
2
|
+
class PackageInstall < Trailblazer::Operation
|
3
|
+
class PackageNameError < StandardError; end
|
4
|
+
|
5
|
+
step Subprocess(Caco::Debian::PackageInstalled),
|
6
|
+
id: "package_installed?",
|
7
|
+
input: [:package],
|
8
|
+
output: []
|
9
|
+
|
10
|
+
fail Subprocess(Caco::Executer),
|
11
|
+
Output(:success) => End(:success),
|
12
|
+
input: ->(_ctx, package:, **) {{
|
13
|
+
command: "apt-get install -y #{package}"
|
14
|
+
}},
|
15
|
+
output: { exit_code: :package_install_exit_code, output: :package_install_output },
|
16
|
+
id: "package_install"
|
17
|
+
|
18
|
+
step ->(ctx, **) { ctx[:already_installed] = true },
|
19
|
+
id: :package_already_installed!
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Caco::Debian
|
2
|
+
class PackageInstalled < Trailblazer::Operation
|
3
|
+
step Subprocess(Caco::Executer),
|
4
|
+
input: ->(_ctx, package:, **) {{
|
5
|
+
command: "dpkg -s #{package}"
|
6
|
+
}},
|
7
|
+
output: { exit_code: :command_exit_code, output: :command_output },
|
8
|
+
id: "dpkg"
|
9
|
+
|
10
|
+
step Subprocess(Caco::Finder),
|
11
|
+
input: ->(_ctx, package:, **) {{
|
12
|
+
command: "dpkg-query -W -f='${Status} ${Version}\n' #{package}",
|
13
|
+
regexp: /^install/
|
14
|
+
}},
|
15
|
+
id: "dpkg_query"
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Caco::Debian
|
2
|
+
class ServiceEnable < Trailblazer::Operation
|
3
|
+
step Subprocess(Caco::Executer),
|
4
|
+
input: ->(_ctx, service:, **) {{
|
5
|
+
command: "systemctl list-units --full -all | grep -Fq \"#{service}.service\""
|
6
|
+
}},
|
7
|
+
id: :check_service_exist
|
8
|
+
|
9
|
+
step Subprocess(Class.new(Caco::Executer)),
|
10
|
+
Output(:success) => End(:success),
|
11
|
+
Output(:failure) => Track(:success),
|
12
|
+
input: ->(_ctx, service:, **) {{
|
13
|
+
command: "systemctl is-enabled #{service}.service"
|
14
|
+
}},
|
15
|
+
id: :check_service_enabled
|
16
|
+
|
17
|
+
step Subprocess(Class.new(Caco::Executer)),
|
18
|
+
input: ->(_ctx, service:, **) {{
|
19
|
+
command: "systemctl enable #{service}.service"
|
20
|
+
}},
|
21
|
+
id: :enable_service
|
22
|
+
|
23
|
+
step ->(ctx, **) { ctx[:enabled] = true },
|
24
|
+
id: :mark_enabled
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Caco::Debian
|
2
|
+
class ServiceInstall < Trailblazer::Operation
|
3
|
+
step ->(ctx, name:, **) {
|
4
|
+
ctx[:service_path] = "/etc/systemd/system/#{name}.service"
|
5
|
+
},
|
6
|
+
id: :generate_service_path
|
7
|
+
|
8
|
+
step :generate_template_content
|
9
|
+
|
10
|
+
step Subprocess(Caco::FileWriter),
|
11
|
+
input: ->(_ctx, service_path:, template_content:, **) {{
|
12
|
+
path: service_path,
|
13
|
+
content: template_content
|
14
|
+
}}
|
15
|
+
|
16
|
+
step Subprocess(Caco::Executer),
|
17
|
+
input: ->(_ctx, **) {{
|
18
|
+
command: "systemctl daemon-reload",
|
19
|
+
}},
|
20
|
+
id: "systemctl_reload"
|
21
|
+
|
22
|
+
def generate_template_content(ctx, description: nil, environment_file: nil, environment_vars: nil, command:, **)
|
23
|
+
ctx[:template_content] = Caco::Debian::Cell::Service.(
|
24
|
+
command: command,
|
25
|
+
description: description,
|
26
|
+
environment_file: environment_file,
|
27
|
+
environment_vars: environment_vars,
|
28
|
+
).to_s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Caco::Debian
|
2
|
+
class UserHome < Trailblazer::Operation
|
3
|
+
step Subprocess(Caco::FileReader),
|
4
|
+
input: ->(_ctx, **) {{
|
5
|
+
path: "/etc/passwd",
|
6
|
+
}},
|
7
|
+
output: { output: :passwd_output }
|
8
|
+
step :find_user_home
|
9
|
+
|
10
|
+
def find_user_home(ctx, user:, passwd_output:, **)
|
11
|
+
match = passwd_output.match(/^#{user}:[^:]*:[^:]*:[^:]*:[^:]*:([^:]*):.*$/)
|
12
|
+
return false unless match
|
13
|
+
|
14
|
+
ctx[:user_home] = match[1]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# File Managed, Dot Not Edit
|
2
|
+
[Unit]
|
3
|
+
Description=<%= description %>
|
4
|
+
After=syslog.target network.target network-online.target
|
5
|
+
|
6
|
+
[Service]
|
7
|
+
<% if environment_file %>
|
8
|
+
EnvironmentFile=<%= environment_file %>
|
9
|
+
<% end %>
|
10
|
+
<% environment_vars.each do |env| %>
|
11
|
+
Environment=<%= env %>
|
12
|
+
<% end %>
|
13
|
+
User=root
|
14
|
+
Restart=on-failure
|
15
|
+
ExecStart=<%= command %>
|
16
|
+
|
17
|
+
[Install]
|
18
|
+
WantedBy=multi-user.target
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# File Managed, Dot Not Edit
|
2
|
+
deb <%= mirror_url %> stretch main
|
3
|
+
deb-src <%= mirror_url %> stretch main
|
4
|
+
|
5
|
+
deb http://security.debian.org/debian-security stretch/updates main
|
6
|
+
deb-src http://security.debian.org/debian-security stretch/updates main
|
7
|
+
|
8
|
+
# stretch-updates, previously known as 'volatile'
|
9
|
+
deb <%= mirror_url %> stretch-updates main
|
10
|
+
deb-src <%= mirror_url %> stretch-updates main
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require "open-uri"
|
3
|
+
|
4
|
+
module Caco
|
5
|
+
class Downloader < Trailblazer::Operation
|
6
|
+
Stubbed = Class.new(Trailblazer::Activity::Signal)
|
7
|
+
|
8
|
+
step ->(_ctx, stubbed_file: nil, **) {
|
9
|
+
stubbed_file ? Stubbed : true
|
10
|
+
},
|
11
|
+
Output(Stubbed, :stubbed) => Track(:stubbed),
|
12
|
+
id: :check_stubbed
|
13
|
+
|
14
|
+
step ->(ctx, url:, **) {
|
15
|
+
ctx[:tempfile] = Down.download(url)
|
16
|
+
},
|
17
|
+
id: :download_file
|
18
|
+
|
19
|
+
step ->(ctx, stubbed_file:, **) {
|
20
|
+
ctx[:tempfile] = File.new(ctx[:stubbed_file])
|
21
|
+
},
|
22
|
+
magnetic_to: :stubbed,
|
23
|
+
id: :stubbed_download_file
|
24
|
+
|
25
|
+
step ->(_ctx, **) {
|
26
|
+
true
|
27
|
+
},
|
28
|
+
id: :check_md5
|
29
|
+
|
30
|
+
step :write_file
|
31
|
+
|
32
|
+
def write_file(ctx, tempfile:, dest:, **)
|
33
|
+
if Caco.config.write_files
|
34
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
35
|
+
File.rename tempfile.path, dest
|
36
|
+
else
|
37
|
+
tempfile.unlink
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Caco
|
2
|
+
class Executer < Trailblazer::Operation
|
3
|
+
step :execute!
|
4
|
+
|
5
|
+
def execute!(ctx, command:, **)
|
6
|
+
s, e, o, error = self.class.send(:execute, command)
|
7
|
+
ctx[:signal] = [s, e, o, error]
|
8
|
+
ctx[:exit_code] = e
|
9
|
+
ctx[:output] = o
|
10
|
+
ctx[:stderr] = error
|
11
|
+
|
12
|
+
return s
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
private
|
17
|
+
def execute(command)
|
18
|
+
stdout = nil
|
19
|
+
stderr = nil
|
20
|
+
pid = nil
|
21
|
+
exit_status = nil
|
22
|
+
Open3.popen3(*command) do |i, o, e, t|
|
23
|
+
pid = t.pid
|
24
|
+
stdout = o.read
|
25
|
+
stderr = e.read
|
26
|
+
exit_status = t.value
|
27
|
+
end
|
28
|
+
return exit_status.success?, exit_status.exitstatus, stdout, stderr
|
29
|
+
end
|
30
|
+
end
|
31
|
+
extend ClassMethods
|
32
|
+
end
|
33
|
+
end
|
data/lib/caco/facter.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
module Caco::Facter
|
2
|
+
class KeyNotFoundError < StandardError; end
|
3
|
+
|
4
|
+
module ClassMethods
|
5
|
+
@@fake_data = nil
|
6
|
+
|
7
|
+
def set_fake_data=(data)
|
8
|
+
@@fake_data = data
|
9
|
+
end
|
10
|
+
|
11
|
+
def use_fake(data, &block)
|
12
|
+
old_fake_data = @@fake_data
|
13
|
+
@@fake_data = data
|
14
|
+
|
15
|
+
yield
|
16
|
+
|
17
|
+
@@fake_data = old_fake_data
|
18
|
+
end
|
19
|
+
|
20
|
+
def call(*items)
|
21
|
+
value = json_data(*items).dig(*items)
|
22
|
+
raise KeyNotFoundError.new("#{items.join(":")} not found") unless value
|
23
|
+
value
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def json_data(*items)
|
28
|
+
return @@fake_data unless @@fake_data.nil?
|
29
|
+
|
30
|
+
@@parsed_data ||= JSON.parse(external_facter_data)
|
31
|
+
end
|
32
|
+
|
33
|
+
def external_facter_data
|
34
|
+
facter_path = Caco::Executer.(command: "which facter")[:output].chomp!
|
35
|
+
result = Caco::Executer.(command: "#{facter_path} -j")
|
36
|
+
result[:output]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
extend ClassMethods
|
41
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Caco::FileLink < Trailblazer::Operation
|
2
|
+
pass :link_exist?
|
3
|
+
pass :target_exist?
|
4
|
+
step :link_same_target?,
|
5
|
+
Output(:success) => End(:success),
|
6
|
+
Output(:failure) => Track(:success)
|
7
|
+
step :ensure_target!
|
8
|
+
step :create_link!
|
9
|
+
|
10
|
+
def link_exist?(ctx, link:, **)
|
11
|
+
ctx[:link_exist] = !!File.lstat(link) rescue false
|
12
|
+
ctx[:link_realpath] = File.realdirpath(link) rescue false
|
13
|
+
ctx[:link_exist]
|
14
|
+
end
|
15
|
+
|
16
|
+
def target_exist?(ctx, target:, **)
|
17
|
+
ctx[:target_exist] = File.exist?(target)
|
18
|
+
ctx[:target_realpath] = File.realdirpath(target) rescue nil
|
19
|
+
ctx[:target_exist]
|
20
|
+
end
|
21
|
+
|
22
|
+
def link_same_target?(ctx, target_realpath:, link_realpath:, **)
|
23
|
+
ctx[:link_same_target] = (target_realpath == link_realpath)
|
24
|
+
end
|
25
|
+
|
26
|
+
def ensure_target!(ctx, target_exist:, ensure_target: false, **)
|
27
|
+
return false if !target_exist && ensure_target
|
28
|
+
true
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_link!(ctx, target:, link:, link_exist:, link_same_target:, **)
|
32
|
+
ctx[:force] = (link_exist && !link_same_target)
|
33
|
+
FileUtils.ln_s target, link, force: ctx[:force]
|
34
|
+
ctx[:link_created] = true
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Caco::FileReader < Trailblazer::Operation
|
2
|
+
UseCustomRoot = Class.new(Trailblazer::Activity::Signal)
|
3
|
+
|
4
|
+
step :use_custom_root,
|
5
|
+
Output(UseCustomRoot, :use_custom_root) => Track(:success)
|
6
|
+
|
7
|
+
step :file_exist
|
8
|
+
step :read_file, Output(Trailblazer::Activity::Left, :failure) => End(:success)
|
9
|
+
|
10
|
+
def use_custom_root(ctx, path:, **)
|
11
|
+
return true unless Caco.config.write_files_root
|
12
|
+
ctx[:path] = "#{Caco.config.write_files_root}#{ctx[:path]}"
|
13
|
+
|
14
|
+
UseCustomRoot
|
15
|
+
end
|
16
|
+
|
17
|
+
def file_exist(ctx, path:, **)
|
18
|
+
ctx[:file_exist] = File.exist?(path)
|
19
|
+
end
|
20
|
+
|
21
|
+
def read_file(ctx, path:, **)
|
22
|
+
ctx[:output] = File.read(path)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class Caco::FileWriter < Trailblazer::Operation
|
2
|
+
SameMD5 = Class.new(Trailblazer::Activity::Signal)
|
3
|
+
DifferentMD5 = Class.new(Trailblazer::Activity::Signal)
|
4
|
+
UseCustomRoot = Class.new(Trailblazer::Activity::Signal)
|
5
|
+
|
6
|
+
step :use_custom_root,
|
7
|
+
Output(UseCustomRoot, :use_custom_root) => Track(:success)
|
8
|
+
|
9
|
+
pass :file_exist
|
10
|
+
step :calculate_md5
|
11
|
+
step :compare_md5,
|
12
|
+
Output(SameMD5, :same_md5) => End(:success),
|
13
|
+
Output(DifferentMD5, :success) => Track(:success)
|
14
|
+
step :mkdir_p
|
15
|
+
step :write_file
|
16
|
+
|
17
|
+
def use_custom_root(ctx, path:, **)
|
18
|
+
return true unless Caco.config.write_files_root
|
19
|
+
unless ctx[:path].start_with?(Caco.config.write_files_root.to_s)
|
20
|
+
ctx[:path] = "#{Caco.config.write_files_root}#{ctx[:path]}"
|
21
|
+
end
|
22
|
+
UseCustomRoot
|
23
|
+
end
|
24
|
+
|
25
|
+
def file_exist(ctx, path:, **)
|
26
|
+
ctx[:file_exist] = File.exist?(path)
|
27
|
+
ctx[:file_created] = !ctx[:file_exist]
|
28
|
+
ctx[:file_exist]
|
29
|
+
end
|
30
|
+
|
31
|
+
def calculate_md5(ctx, path:, file_exist:, content:, **)
|
32
|
+
ctx[:current_md5] = (file_exist ? Digest::MD5.hexdigest(File.read(path)) : "")
|
33
|
+
ctx[:content_md5] = Digest::MD5.hexdigest(content)
|
34
|
+
end
|
35
|
+
|
36
|
+
def compare_md5(ctx, content_md5:, current_md5:, **)
|
37
|
+
different_md5 = (content_md5 != current_md5)
|
38
|
+
ctx[:file_changed] = different_md5 ? true : false
|
39
|
+
different_md5 ? DifferentMD5 : SameMD5
|
40
|
+
end
|
41
|
+
|
42
|
+
def mkdir_p(ctx, path:, **)
|
43
|
+
dirname = File.dirname(path)
|
44
|
+
if Caco.config.write_files
|
45
|
+
FileUtils.mkdir_p(dirname) unless File.exist?(dirname)
|
46
|
+
end
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
def write_file(ctx, path:, content:, file_exist:, **)
|
51
|
+
if Caco.config.write_files
|
52
|
+
File.write(path, content)
|
53
|
+
end
|
54
|
+
ctx[:file_created] = !file_exist
|
55
|
+
ctx[:file_changed] = true
|
56
|
+
end
|
57
|
+
end
|