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 |