-
-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add --keep
argument to prevent deleting images
#151
Add --keep
argument to prevent deleting images
#151
Conversation
.value_name("KEEP") | ||
.short("k") | ||
.long(KEEP_OPTION) | ||
.multiple(true) |
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.
Not sure if you'll like this structure, but I went with a multiple argument (with one value each) so the usage is:
--keep regex1 --keep regex2
I thought this might be preferable to having a single very convoluted regex for more complex setups.
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.
Seems reasonable.
Thank you for this contribution! I will take a look as soon as I can. |
My pleasure. This is my first open source contribution to the rust community so please don't hesitate to let me know if you'd rather I do something differently. And thank you for this project; it has been quite helpful. |
Hi @keelerm84, sorry for the long delay on this. Would you mind rebasing onto the latest commit? |
`--keep` is a new argument that allows users to specify one or more regular expressions which, when matched against an image name, will prevent that image from being deleted. This is particularly useful for images that may require long re-build times and so should not be cleaned up as part of normal system maintenance.
c460ed5
to
ce93af6
Compare
Hey @stepchowfun, no problem. I have updated the commit as requested. Thanks for following up on this! |
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.
Overall seems reasonable. I left a few suggestions.
But one thing I'm wondering is: why does --keep
filter on the repository name? Why not repository:tag
, so that users could specify that they want to keep only a specific image, not all images from the repository?
src/main.rs
Outdated
@@ -102,6 +105,16 @@ fn settings() -> io::Result<Settings> { | |||
DEFAULT_THRESHOLD.code_str(), | |||
)), | |||
) | |||
.arg( | |||
Arg::with_name(KEEP_OPTION) | |||
.value_name("KEEP") |
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 think the value name should be REGEX
(or similar).
src/main.rs
Outdated
.multiple(true) | ||
.number_of_values(1) | ||
.required(false) | ||
.help("Regular expression of repository names to keep despite space constraints"), |
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.
Can we use the same verb tense/usage as the other flags? So maybe something like:
Prevents Docuum from deleting images from repositories matching <REGEX>
.value_name("KEEP") | ||
.short("k") | ||
.long(KEEP_OPTION) | ||
.multiple(true) |
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.
Seems reasonable.
.short("k") | ||
.long(KEEP_OPTION) | ||
.multiple(true) | ||
.number_of_values(1) |
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 not the default when value_name
is specified? What happens if this is omitted?
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 you remove this, you can actually specify multiple with the same flag. So with my latest change you can now do:
--keep pattern1 pattern2 pattern3 --keep pattern4 pattern5
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.
Oh I see—thanks for explaining it. Actually, would you mind changing it back? I'm worried about how this will interact with other flags that might be added in the future. Having one pattern per flag seems like a safer choice.
src/main.rs
Outdated
.long(KEEP_OPTION) | ||
.multiple(true) | ||
.number_of_values(1) | ||
.required(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.
Wondering the same thing about this: isn't this the default?
src/main.rs
Outdated
Ok(set) => Some(set), | ||
Err(_) => { | ||
return Err(io::Error::new( | ||
io::ErrorKind::InvalidInput, |
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.
While we're here, would you mind changing line 127 to io::ErrorKind::InvalidInput
as well? I think it's a better choice than what I had there (io::ErrorKind::Other
).
src/main.rs
Outdated
Err(_) => { | ||
return Err(io::Error::new( | ||
io::ErrorKind::InvalidInput, | ||
"Invalid regex format provided", |
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 ugly would it be if we just used the error message from RegexSet::new
? I think it would be good to include the original error message so the user knows what they messed up, but not if it's too ugly.
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 made this change. The format isn't very ugly and it is way more helpful. Example:
[2021-07-13 21:17:11 -04:00 ERROR] regex parse error:
(\bkong\b|
^
error: unclosed group
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.
Hah, I think it's kind of ugly since the message isn't capitalized and isn't a sentence, unlike all the error messages we emit. But I agree it's more helpful!
src/run.rs
Outdated
} else { | ||
return Err(io::Error::new( | ||
io::ErrorKind::Other, | ||
"Failed to split image ID and date.", |
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.
Can we update this error message? Maybe just Failed to parse image list output from Docker.
or something like that.
src/run.rs
Outdated
"Skipping image {} which matches one or more of the provided regexs", | ||
image_node.image_info.repository | ||
); | ||
return 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.
If you don't mind, I have a slight preference for formatting the lambda like this (instead of the imperative-style return
):
if regex_set.is_match(&image_node.image_info.repository) { {
info!(...);
false
} else {
true
}
src/run.rs
Outdated
if regex_set.is_match(&image_node.image_info.repository) { | ||
info!( | ||
"Skipping image {} which matches one or more of the provided regexs", | ||
image_node.image_info.repository |
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 failing lint
task wants you to put a trailing comma at the end of this line.)
Thank you for the thorough and detailed feedback. I believe I have addressed each bit as requested. Happy to change anything else you'd like. |
info!( | ||
"Skipping image {} which matches one or more of the provided regexs", | ||
image_node.image_info.repository_tag | ||
); |
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:
info!(
"Ignored image {} due to the {} flag.",
image_node.image_info.repository_tag.code_str(),
"--keep".code_str(),
);
(There was missing punctuation and a missing trailing comma, and I think it is good to reference the flag that caused the image to be skipped. Also "regexs" seemed like a strange pluralization to me.)
Looking great to me. I added a couple more comments, but otherwise I think this is pretty much there. |
I appreciate your continued patience while I work through these issues for you. Thank you, and please let me know if there is anything else you'd like me to address! |
src/main.rs
Outdated
.long(KEEP_OPTION) | ||
.multiple(true) | ||
.number_of_values(1) | ||
.help("Prevents Docuum from deleting repository:tag images that match the provided <REGEX>"), |
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.
Seems like the linter is complaining that this line is too long. Can we break up the string somewhere?
I think you're the patient one here. Thanks for being receptive to all the feedback. BTW, if you want to run all the linters and stuff locally (instead of waiting for me to approve the CI jobs), I recommend installing Toast. Then you can just run I'll merge this PR once it passes the CI checks. |
@@ -543,6 +550,26 @@ fn vacuum(state: &mut State, threshold: &Byte) -> io::Result<()> { | |||
.then(y.ancestors.cmp(&x.ancestors)) | |||
}); | |||
|
|||
// If the user provided the keep argument, we need to filter out those images which match the |
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.
Tiny nit: could you change it to this:
// If the user provided the `--keep` argument, ...
(Add the dashes and backticks.)
Installed and linted locally without complaint so 🤞 |
parent_id: None, // This will be populated below. | ||
created_since_epoch: parse_docker_date(&date_str)?, | ||
}); | ||
let image_parts = trimmed_line.split('\t').take(3).collect::<Vec<_>>(); |
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'm thinking it might be safer to remove the .take(3)
, so that the pattern match on the following line will fail (as it should) if there are more than 3 parts in the line.
Seems like there is something we overlooked: the same image can have multiple tags. So unfortunately what we have here is not quite right (I think): an image might still be deleted even if one of its tags matches the regex(es), because another one of its tags might not. I am going to hold off on releasing a new version until I can fix this. If there isn't an easy fix, I might have to revert this PR—but hopefully I can fix the problem instead of doing that. |
I've fixed the aforementioned issue in #168 and released this new feature in v0.20.0. Unfortunately the fix was fairly involved, which is why it took me a few weeks to do. But I think now the code in better shape thanks to the the events set in motion by this PR. So overall I'm glad we went on this journey. |
Thank you for addressing the issue and having worked with me as much as you did. As I mentioned before, this was my first open source contribution to a rust project and I want to thank you again for being as welcoming and accommodating as you were. |
--keep
is a new argument that allows users to specify one or moreregular expressions which, when matched against an image name, will
prevent that image from being deleted.
This is particularly useful for images that may require long re-build
times and so should not be cleaned up as part of normal system
maintenance.
Status: Ready
Fixes: #129