-
Notifications
You must be signed in to change notification settings - Fork 33
fixes #21198 - unmounts/removes snapshots if failure #549
Conversation
Issues: #21198 |
@evgeni - could you review this please? You're the best versed at snapshots 💯 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the change looks fine from a logic perspective, but I think we can refactor the code to be cleaner ;)
katello/helper.rb
Outdated
@@ -13,7 +13,7 @@ def error_message | |||
end | |||
|
|||
def foreman_rpm_installed? | |||
system("rpm -q foreman") | |||
system("rpm -q foreman >/dev/null") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this change relevant here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It prints the output needlessly, and since we aren't doing anything except distinguishing satellite from capsule, I don't think the output created should be displayed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this has been fixed via http://projects.theforeman.org/issues/21219 now
katello/backup.rb
Outdated
@@ -32,6 +32,12 @@ def cleanup(exitstatus=-1) | |||
puts "Cleaning up backup folder and starting any stopped services... " | |||
FileUtils.cd("/") | |||
FileUtils.rm_rf @dir unless @options[:no_subdir] | |||
if @options[:snapshot] | |||
@databases.each do |database| | |||
system("umount #{File.join(@mountdir, database)} >/dev/null") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is more or less duplicating code from https://github.com/cfouant/katello-packaging/blob/86547ae08f4eaebbddc6a5623ec847c68c42be41/katello/backup.rb#L195-L200, shall we move these lines into an own function and call it here and in L195?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was considering the same, however, I wanted to suppress the output here, as the output is terrible if there are no mounted filesystems. I will add that into the function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On second thought, I think these do need to be kept separate. We want the process in backup/destroy to go through the run_cmd method; however, as we've previously found in calling run_cmd in cleanup, we can end up caught in an endless loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haha. right. I wonder if we should teach run_cmd something like "ignore_all_errors" next to the list of accepted exit codes. anyways, that is a discussion for another PR/redmine.
let me see how this code actually runs, and ack that PR afterwards.
would you mind adding a comment "not using run_cmd here because …" so that we don't forget that in the future?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely :)
katello/backup.rb
Outdated
if @options[:snapshot] | ||
@databases.each do |database| | ||
system("umount #{File.join(@mountdir, database)} >/dev/null") | ||
system("lvremove -f #{get_snapshot_location(database)} >/dev/null") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should first get get_snapshot_location(database)
and only execute lvremove
if the get actually returned anything. Otherwise (when the snapshot in question does not exist), you end up with ugly errors:
No command with matching syntax recognised. Run 'lvremove --help' for more information.
Correct command syntax is:
katello/backup.rb
Outdated
def cleanup(exitstatus=-1) | ||
puts "Cleaning up backup folder and starting any stopped services... " | ||
FileUtils.cd("/") | ||
FileUtils.rm_rf @dir unless @options[:no_subdir] | ||
if @options[:snapshot] | ||
@databases.each do |database| | ||
system("umount #{File.join(@mountdir, database)} >/dev/null") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will still output an error (but continue), if the mount point is not mounted:
umount: /var/snap/mongodb: mountpoint not found
@evgeni - thanks for the suggestions, thanks for testing! |
katello/helper.rb
Outdated
# using backticks here so there is no output | ||
`rpm -q foreman` | ||
$?.success? | ||
system("rpm -q foreman >/dev/null") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either way works fine for me as long as there is no output. Do you mind adding a space after then >
pipe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are going to update to anything across the scripts, using http://ruby-doc.org/stdlib-1.9.3/libdoc/open3/rdoc/Open3.html#method-c-popen3 would be ideal. It starts a new external process that can be monitored. I'm not saying this should be done in this PR, but would be worth looking into more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We definitely do not want to update across the scripts at this time. system() returns a true/false/nil value, and run_cmd returns output. Updating with the space now 👍
@@ -28,10 +28,20 @@ def initialize(foreman_proxy_content, foreman_proxy, program, accepted_scenarios | |||
setup_opt_parser | |||
end | |||
|
|||
# do not use run_cmd() inside this method, to avoid a recursive loop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mind being a bit more verbose and say you aren't using run_cmd inside cleanup method because run_cmd calls cleanup and will cause an infinite loop? (I only ask because I was confused to where the loop would come from at first)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done!
ping @evgeni @johnpmitsch - could i haz re-review when you get the opportunity? Thanks! |
LGTM 👍 (I'll let evgeni approve to merge) |
katello/backup.rb
Outdated
if @options[:snapshot] | ||
@databases.each do |database| | ||
mount_location = File.join(@mountdir, database) | ||
system("umount #{mount_location}") if system("mount | grep #{mount_location}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of doing mount | grep
, how about that function:
def is_mounted(path)
mounts = File.readlines('/proc/mounts')
mounts.each do |mount|
mount = mount.split
return true if mount[1] == path
end
return false
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems much more costly and clunkier? I think it's also in the style guidelines to do avoid 'return true/false'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about
if File.readlines('/proc/mounts').grep(/#{mount_location}).any?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 🐑
merged! thanks @cfouant ! |
No description provided.