-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinstall_module.rb
109 lines (95 loc) · 3.92 KB
/
install_module.rb
1
2
3
4
5
6
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
#!/usr/bin/env ruby
require 'date'
require 'set'
require_relative 'loggers'
# TODO: make a module or something for this file? organize into a directory like `lib/`?
def verify_module(module_name, verified_modules)
if verified_modules.include?(module_name)
log_debug "Module '#{module_name}' has already been verified"
return
end
module_path = "#{__dir__}/modules/#{module_name}"
unless Dir.exist?(module_path)
log_error "Module '#{module_name}' does not exist"
# TODO: raise exception instead
raise StandardError, "Module '#{module_name}' does not exist"
end
# read all dependencies and attempt to verify them as needed
IO.foreach("#{module_path}/dependencies.txt") do |dependency|
# remove trailing whitespace
dependency = dependency.strip
log_debug "Verifying dependency '#{dependency}' for module '#{module_name}'"
begin
verify_module dependency, verified_modules
rescue StandardError => e
log_error "Failed to verify dependency: #{e.message}"
# TODO: what to do here instead of raising?
raise e
end
end
# verify module to see if it has already been installed
verify_exit_status = execute_module_script("#{module_path}/verify.sh", should_log_output: true)
if verify_exit_status.zero?
log_debug "Module '#{module_name}' is already installed"
verified_modules << module_name
return
end
end
def install_module(module_name, verified_modules)
if verified_modules.include?(module_name)
log_debug "Module '#{module_name}' has already been verified"
return
end
module_path = "#{__dir__}/modules/#{module_name}"
unless Dir.exist?(module_path)
log_error "Module '#{module_name}' does not exist"
# TODO: raise exception instead
raise StandardError, "Module '#{module_name}' does not exist"
end
# read all dependencies and attempt to install them as needed
IO.foreach("#{module_path}/dependencies.txt") do |dependency|
# remove trailing whitespace
dependency = dependency.strip
log_debug "Checking dependency '#{dependency}' for module '#{module_name}'"
begin
install_module dependency, verified_modules
rescue StandardError => e
log_error "Failed to install dependency: #{e.message}"
raise e
end
end
# TODO: validate module has a verification script
# verify module to see if it has already been installed
verify_exit_status = execute_module_script("#{module_path}/verify.sh", should_log_output: true)
if verify_exit_status.zero?
log_debug "Module '#{module_name}' is already installed"
verified_modules << module_name
return
end
# execute installation script
install_exit_status = execute_module_script("#{module_path}/install.sh")
if install_exit_status != 0
log_error "Failed to install module '#{module_name}'"
log_error "Exit code: #{install_exit_status}"
raise StandardError, "Failed to install module '#{module_name}'"
end
# re-run verification to confirm installation has succeeded
verify_exit_status = execute_module_script("#{module_path}/verify.sh", should_log_output: true)
if verify_exit_status != 0
log_error "Module '#{module_name}' was installed, but installation is invalid"
raise StandardError, "Module '#{module_name}' was installed, but installation is invalid"
end
# mark module as verified
verified_modules << module_name
log_info "Successfully installed module '#{module_name}'"
end
# TODO: make this private?
def execute_module_script(module_script_path, should_log_output: true)
log_info "Begin output from module script '#{module_script_path}'" if should_log_output
# TODO: what happens if the process prompts for input?
spawn_opts = should_log_output ? {} : { :out => File::NULL, :err => File::NULL }
# TODO: is the `bash -c` even needed? perhaps an `exec` instead?
system 'bash', '-c', module_script_path, spawn_opts
log_info "End output from module script '#{module_script_path}'" if should_log_output
$?.exitstatus
end