Dev commited on 2018-06-17 09:01:35
Showing 5 changed files, with 50 additions and 37 deletions.
... | ... |
@@ -10,17 +10,20 @@ |
10 | 10 |
desired_state: installed |
11 | 11 |
|
12 | 12 |
- files: |
13 |
- - path: /tmp/hello_world.php |
|
13 |
+ - path: /var/www/html/index.php |
|
14 | 14 |
owner: dev |
15 | 15 |
group: dev |
16 | 16 |
mode: '0664' |
17 | 17 |
local_file: /home/dev/src/rcm/resources/hello_world.php |
18 | 18 |
desired_state: present |
19 | 19 |
|
20 |
+ - path: /var/www/html/index.html |
|
21 |
+ desired_state: absent |
|
22 |
+ |
|
20 | 23 |
- services: |
21 | 24 |
- name: apache2 |
22 | 25 |
dependencies: |
23 | 26 |
- packages: |
24 | 27 |
- name: libapache2-mod-php |
25 | 28 |
- files: |
26 |
- - path: /tmp/hello_world.php |
|
29 |
+ - path: /var/www/html/index.php |
... | ... |
@@ -19,10 +19,10 @@ module RCM |
19 | 19 |
@logger.debug("Setting owner as #{file.owner}:#{file.group} and mode as #{file.mode} on #{file.path}") |
20 | 20 |
# Will throw exception if something poopy happens |
21 | 21 |
::FileUtils.chown(file.owner, file.group, file.path) |
22 |
- ::FileUtils.chmod(file.mode, file.path) |
|
22 |
+ ::FileUtils.chmod(file.mode.to_i, file.path) |
|
23 | 23 |
|
24 | 24 |
file.changed = true |
25 |
- file |
|
25 |
+ 0 |
|
26 | 26 |
end |
27 | 27 |
|
28 | 28 |
def copy(file) |
... | ... |
@@ -30,10 +30,18 @@ module RCM |
30 | 30 |
@logger.debug("Ensuring #{dir} exsits.") |
31 | 31 |
::FileUtils.mkdir_p(dir) |
32 | 32 |
@logger.debug("Copying #{file.src_path} to #{file.path}.") |
33 |
- ::FileUtils.copy(file.src_path, file.path, remove_destination: true) |
|
34 | 33 |
|
34 |
+ begin |
|
35 |
+ ::FileUtils.copy_entry(file.src_path, file.path, remove_destination: true) |
|
36 |
+ rescue |
|
37 |
+ error_msg = "Could not copy #{file.src_path} to #{file.path}." |
|
38 |
+ @logger.fatal(error_msg) |
|
39 |
+ return 1 |
|
40 |
+ end |
|
41 |
+ |
|
42 |
+ file.state = ::RCM::File::PRESENT |
|
35 | 43 |
file.changed = true |
36 |
- file |
|
44 |
+ 0 |
|
37 | 45 |
end |
38 | 46 |
|
39 | 47 |
def remove(file) |
... | ... |
@@ -41,8 +49,9 @@ module RCM |
41 | 49 |
|
42 | 50 |
@logger.debug("Removing #{file.path}.") |
43 | 51 |
::FileUtils.rm(file.path) |
52 |
+ file.state = ::RCM::File::ABSENT |
|
44 | 53 |
file.changed = true |
45 |
- file |
|
54 |
+ 0 |
|
46 | 55 |
end |
47 | 56 |
|
48 | 57 |
def initialize(logger) |
... | ... |
@@ -54,7 +63,7 @@ module RCM |
54 | 63 |
uids = get_id_to_name_mapping('/etc/passwd') |
55 | 64 |
gids = get_id_to_name_mapping('/etc/group') |
56 | 65 |
wanted_files.each do |path, p| |
57 |
- f = ::RCM::File.new('', '', '', '', '') |
|
66 |
+ f = ::RCM::File.new(path, '', '', '', '', ::RCM::File::ABSENT) |
|
58 | 67 |
# Put in an empty object if file does not exist |
59 | 68 |
unless ::File.exist?(path) |
60 | 69 |
got[path] = f |
... | ... |
@@ -66,6 +75,7 @@ module RCM |
66 | 75 |
f.owner = uids[f_stat.uid.to_s] |
67 | 76 |
f.group = gids[f_stat.gid.to_s] |
68 | 77 |
f.mode = f_stat.mode.to_s(8)[-4, 4] |
78 |
+ f.state = ::RCM::File::PRESENT |
|
69 | 79 |
got[path] = f |
70 | 80 |
end |
71 | 81 |
|
... | ... |
@@ -27,8 +27,11 @@ module RCM |
27 | 27 |
def restart(service) |
28 | 28 |
@logger.debug("Restarting #{service.name}") |
29 | 29 |
status = ::RCM.cmd("#{SYS_SERVICE_MGR} #{service.name} restart") |
30 |
- error_msg = "Failed to restart #{service.name}.\n\nstderr:\n#{status.error}\n\nstdout:\n#{status.output}" |
|
30 |
+ unless status[:exit_code] == 0 |
|
31 |
+ error_msg = "Failed to restart #{service.name}.\n\nstderr:\n#{status[:error]}\n\nstdout:\n#{status[:output]}" |
|
31 | 32 |
@logger.fatal(error_msg) |
32 | 33 |
end |
34 |
+ |
|
35 |
+ end |
|
33 | 36 |
end |
34 | 37 |
end |
... | ... |
@@ -2,26 +2,32 @@ require 'fileutils' |
2 | 2 |
|
3 | 3 |
module RCM |
4 | 4 |
class File |
5 |
- attr_accessor :path, :owner, :group, :mode, :src_path, :changed |
|
5 |
+ attr_accessor :path, :owner, :group, :mode, :state, :src_path, :changed |
|
6 |
+ |
|
7 |
+ PRESENT = 'present'.freeze |
|
8 |
+ ABSENT = 'absent'.freeze |
|
6 | 9 |
|
7 | 10 |
def ==(other) |
8 | 11 |
return false unless other.is_a?(RCM::File) |
9 | 12 |
|
10 |
- return false if @path.empty? || other.path.empty? |
|
13 |
+ # Paths are same and status is absent for both |
|
14 |
+ return true if @state == ABSENT && other.state == ABSENT && @path == other.path |
|
11 | 15 |
|
12 |
- ::FileUtils.compare_file(@path, other.path) && |
|
13 | 16 |
@owner == other.owner && |
14 | 17 |
@group == other.group && |
15 |
- @mode == other.mode |
|
18 |
+ @mode == other.mode && |
|
19 |
+ @state == other.state && |
|
20 |
+ ::FileUtils.compare_file(@path, other.path) |
|
16 | 21 |
|
17 | 22 |
end |
18 | 23 |
|
19 |
- def initialize(path, owner, group, mode, src_path) |
|
24 |
+ def initialize(path, owner, group, mode, src_path, state) |
|
20 | 25 |
@path = path |
21 | 26 |
@owner = owner |
22 | 27 |
@group = group |
23 | 28 |
@mode = mode |
24 | 29 |
@src_path = src_path |
30 |
+ @state = state |
|
25 | 31 |
@changed = false |
26 | 32 |
end |
27 | 33 |
|
... | ... |
@@ -75,9 +75,11 @@ module RCM |
75 | 75 |
end |
76 | 76 |
|
77 | 77 |
def self.parse_files(markup) |
78 |
+ valid_file_states = [::RCM::File::PRESENT, ::RCM::File::ABSENT] |
|
78 | 79 |
markup.each do |d| |
79 |
- raise "\n\n'#{d['local_file']}' is not readable.\n\n" unless ::File.readable?(d['local_file']) |
|
80 |
- f = RCM::File.new(d['path'], d['owner'], d['group'], d['mode'], d['local_file']) |
|
80 |
+ raise "\n\nFile state can only be one of #{valid_file_states.join (', ')}" if (valid_file_states | [d['desired_state']]).empty? |
|
81 |
+ raise "\n\n'#{d['local_file']}' is not readable.\n\n" if d['desired_state'] == ::RCM::File::PRESENT && !::File.readable?(d['local_file']) |
|
82 |
+ f = RCM::File.new(d['path'], d['owner'], d['group'], d['mode'], d['local_file'], d['desired_state']) |
|
81 | 83 |
@@wanted[FILES][d['path']] = f |
82 | 84 |
end |
83 | 85 |
end |
... | ... |
@@ -173,38 +175,27 @@ module RCM |
173 | 175 |
@@wanted[FILES].each do |path, file_obj| |
174 | 176 |
file_on_fs = @@got[FILES][path] |
175 | 177 |
|
178 |
+ if file_on_fs.state == ::RCM::File::PRESENT && file_obj.state == ::RCM::File::ABSENT |
|
179 |
+ @@logger.info("#{path} is present on disk when it should not be. Removing...") |
|
180 |
+ @@file_mgr.remove(file_obj) |
|
181 |
+ next |
|
182 |
+ end |
|
183 |
+ |
|
176 | 184 |
if file_on_fs == file_obj |
177 |
- @@logger.info("#{path} is in expected state.") |
|
185 |
+ @@logger.info("#{path} is in expected state (#{file_on_fs.state}).") |
|
178 | 186 |
next |
179 | 187 |
end |
180 | 188 |
|
181 |
- # try to do minimal changes by finding what is different |
|
182 |
- if file_on_fs.path.empty? |
|
183 |
- # for files, we're not doing explicit state maintenance like we are doing for packages |
|
184 |
- # If file is on disk, file obj will contain the path. |
|
185 | 189 |
@@logger.info("#{path} is not present on disk.") |
186 |
- @@file_mgr.copy(file_obj) |
|
187 |
- @@file_mgr.apply_attributes(file_obj) |
|
188 |
- elsif file_on_fs.mode != file_obj.mode || |
|
189 |
- file_on_fs.owner != file_obj.owner || |
|
190 |
- file_on_fs.group != file_obj.group |
|
191 |
- @@logger.debug("Attributes on #{path} are not in expected state.") |
|
192 |
- @@file_mgr.apply_attributes(file_obj) |
|
193 |
- elsif !::File.cmp(file_obj.src_path, path) |
|
194 |
- @@logger.debug("File contents don't match, even though #{path} is on disk.") |
|
195 |
- @@file_mgr.remove(file_obj) |
|
196 |
- @@file_mgr.copy(file_obj) |
|
197 |
- @@file_mgr.apply_attributes(file_obj) |
|
198 |
- end |
|
190 |
+ status = @@file_mgr.copy(file_obj) |
|
191 |
+ @@file_mgr.apply_attributes(file_obj) if status == 0 |
|
199 | 192 |
|
200 |
- # Set the version correctly |
|
201 |
- @@crackalackin[FILES].push(file_obj) |
|
202 | 193 |
end |
203 | 194 |
end |
204 | 195 |
|
205 | 196 |
def self.restart_services_if_needed |
206 | 197 |
@@wanted[SERVICES].values.each do |svc_obj| |
207 |
- @@svc_manager.restart(svc_obj) if @@svc_mgr.dependencies_changed?(svc_obj) |
|
198 |
+ @@svc_mgr.restart(svc_obj) if @@svc_mgr.dependencies_changed?(svc_obj) |
|
208 | 199 |
end |
209 | 200 |
end |
210 | 201 |
|
211 | 202 |