-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
[Feature request] Archive.extracted to be able to remove top level directory #54012
Comments
So you have an archive, say |
@waynew Now new commit was pushed to the master branch of something and the new artifact was created and we want to deploy it again. But now we have no means to check if the update is actually required since there is no sane version, just "master". So our approach here is to create a md5 sum file for each archive and if this md5 differs from the one we already have on a minion - we do a rollout\extraction. So basically we use a But the problem is that current arg So my proposal is to add the ability for a full cleanup for archive module. Not the diff between, but ensure that extraction will be done in the empty top directory. |
@Oloremo have you looked into the |
@waynew I looked at It was something like this:
|
Try
instead |
@waynew what is the point?.. onchanges will be executed after, right?
|
We figure out why Obviously now we have 3 choises:
|
So, what's the problem with removing |
That's a loaded question. And yes, obviously we could drop the |
I'm confused as to why strip components is breaking anything? And why that would require re-packing your artifacts. Can you create a sample set of commands to duplicate the problem that you're seeing? e.g.
I'm not clear on what part is actually missing here, with what you really want to accomplish. From what I understand, you already have all the pieces available with your existing artifacts and Salt's existing behavior. But if that's not the case, we would like to know. Can you create that mcve? |
@waynew Sorry for the confusion.
This script will create 2 directories which represent the deployment approach we're using. Both these directories will be archived into the archive with the name Now please create this state:
And now we're ready to test. Now copy the And now you could see the issue. List the files in the /tmp/delme/master, they will look like this:
What'd I expect:
because |
@waynew Hi again, just wonder if the comment above makes sense to you |
Hey @Oloremo sorry for the wait, it's been a bit busy around these parts. I've finally had a chance to sit down with this and think some more about it. You're actually right here - the issue is that with the presence of If you wanted to test this out in your own code, take a look at
to
This will make the @terminalmage may have some alternate thoughts about it, but that seems like the most consistent behavior to me. |
@waynew Hi, sorry for the late reply. Plus |
I'll try to draft it soon |
I don't think I agree with this. The intent of the feature is to only delete paths that Salt is managing. It should never be deleting the parent directory, and adding it to the list of paths to be deleted is reckless and will break things for people. |
The "parent directory" in this context is the equivalent of the directory one would |
From what I see looking at the code it actually behaves differently with and without If you have an archive that looks like this:
If you extract this with strip components 1 you will get this directory structure:
If you have another archive like this:
You will end out with this directory structure:
Salt is cleaning When I say there's an inconsistency, this is what I mean. With an empty directory, change it to
What I'm seeing is that with any level Which is also the same behavior that we get without If we're providing a clean command that is supposed to delete files and folders, I'm totally fine with that not removing toplevel files by default, based on the argument that a tarfile shouldn't have any toplevel files. But I have a problem when we're providing multiple ways to (not) do the same thing, and zero ways to accomplish one thing without doing weird hacks like deleting or copying the archive on changes or something. If you're against the idea of deleting toplevel files with |
/me patiently waiting for a decision on implementation |
@waynew This has nothing to do with any special handling for The way the Salt is very conservative about what it will delete, when This is by design. Salt can't know all the ways in which people will use this state. What happens when someone is using "Why would anyone have other things in the destination dir?" you may ask. Well, why would anyone use So, as I have said, removing the parent dir is a Bad Idea:tm:. Don't do it. The best solution I can think of is to allow for the Example SLS: extract:
archive.extracted:
- name: /tmp/delme/master
- source: salt://master.tar.gz
- source_hash: salt://master.tar.gz.md5
- source_hash_update: True
- keep_source: False
- options: "--strip-components=1"
- enforce_toplevel: False
- clean: salt://old_master.tar.gz Note that this would require you to keep the old archive available, and under a different filename. This would not work if the new archive simply takes the place of the old one, with the same URL but different contents. I can work on the code for this, but I'm still in the process of moving into a new house and will not be able to work on this until sometime next week. |
@Oloremo Would that handle your use case? |
@waynew The proposed idea of using the archive as a source of truth for Clean is smart, but the limitation of keeping old archive is very frustrating especially since there is no really any cache control\eviction logic for archives in Salt as far as I know. And our archives are big(1Gb in general and we could deploy many times per day) plus I'm not sure how it will work in the originally described case where archive name is something like And considering all of that, why'd you still think that my original approach with additional and optional argument I mean right now we're more or less thinking how to make a change and not ruin other peoples workflows - I get it! So in that situation, a new argument feels like a best option for me since it won't affect anyone else since it will be disabled by default and could be properly documented on how it suppose to work(I can add it to PR). It may be not the cleanest approach and it's not a smart approach but it feels safe to me. |
I only dislike it because I fundamentally disagree with terminalmage 🙃 That could be because I haven't seen a scenario in which, disregarding Salt entirely, if you were creating a tar file, deleting some files, and extracting an archive over top of it, with Even using Salt I'm not sure how you would get into the situation where you're using Another approach that could work, IIUC, is just to implement a I don't really like adding the extra argument, because it seems like we should already support this behavior already. |
I'm a bit confused right now.
I actually expect them to be removed but my example above shows what "Just delete top directory" approach is just a very straightforward and simple and that's how I believe, would most of the people do if they need to unarchive new archive with something like "master" version on top of the previous one, and yes kinda like with git. So if removing a top-level dir is not an option and patching strip-components logic against salt design and the idea of patching of the clean logic to take file list from the url is very limiting - what other options do we have? :-) Assuming you agree that the current behavior with strip-components + clean behavior is wrong right now. |
But that's not at all what's happening here, and I'm really puzzled as to how you still don't understand this. The top-level files/dirs are ones that are part of the archive. They are not the destination directory. The destination directory (i.e. the Just because you can't think of a reason someone wouldn't want to delete everything in the parent dir when using @Oloremo If that doesn't quite work for you (and I understand how large archives can present problems), I would prefer a separate argument called |
@terminalmage Could you please elaborate on
This is a bit complicated in general since |
We determine the number of top-level dirs to strip via the from the value in the Basically, we would have an additional argument called I know it seems kinda redundant to have two "clean" arguments, but it seems like the best way of achieving the functionality you need, without changing how the |
It may be a bug (on Salt 2018.3.2) , but I found that the archive.extracted always reported changes when test=True, which makes the prereq and directory purge useless as it will always be triggered To get around, I stuck a state to the get the archive local to the minion first, as file.managed works just fine with onchanges. The only breakdown, is if the archive is local but the follow states failed to run, they never will unless the local archive is purged. jdk archive present on minion:
file.managed:
- name: /opt/jdk.tar.gz
- source: salt://binaries/java/{{ jdk_path }}
- makedirs: True
- show_changes: False
jdk directory purged:
file.absent:
- name: /opt/jdk
- onchanges:
- file: jdk archive present on minion
jdk-oracle-openjdk archive extracted:
archive.extracted:
- name: /opt/jdk
- trim_output: 0
- source: /opt/jdk.tar.gz
- options: --strip-components=1
- enforce_toplevel: False
- onchanges_any:
- file: jdk directory purged
- file: jdk archive present on minion |
@terminalmage @waynew
This is basically what I proposed in #54013 right? |
Yeah, but I personally don't like the I'm OK with it conflicting with Also, instead of |
@terminalmage roger that. ill rebase and update this PR |
Excellent |
@terminalmage So I closed the old PR and created a new one, please take a look when you'll have time. It only includes the single very simple test for new logic and I don't really have an idea how to test it properly. |
Thanks! I just did a code review and suggested a few changes. |
Feature merged! |
Description of Issue
I have the following workflow in the ansible:
The idea here is to release applications with a version like "master". It constantly updated and we can't use something like
onlyif: path/to/file
Since it can exist but it could be old. So we rely on the md5 sum and if it's changes - we overwrite old directory by deleting it first and unarchive after.
And since slots are not a thing yet in requisites I'm not particularly sure how to implement this logic in the current state of Salt.
What I tried:
clean: True
argument - it's only removing the diff between current and new files based on file names.overwrite: True
- leads to the state to lose idempotencyprereq
- withfile.absent
- leads to the state to be run every timeVersions Report
2019.02
The text was updated successfully, but these errors were encountered: