-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
feat: Clone only once per PR #2921
Conversation
Tests are broken, I will fix them if we agree that this is a good thing to add. I still don't know how to solve the clone on the |
How about instead of making new function calls within the workingDir struct, we expand the logic of the clone based on the workspace that is passed into it? This would limit the blast radius by avoiding rewriting calls to the Clone function and making how we handle workspace copies (instead of cloning) internal to the function. |
@GenPage we could do that, but if we go this way I believe it would be nice to change the |
@GenPage please see the linked pr #2882 (comment). Tldr. Recloning on new workspaces and copying code from default workspace is an antipattern. We can utilize the |
Hey @nitrocode I'll test the If the |
@nitrocode @Fabianoshz Apologies for delaying in response, I've been out sick. I completely agree that re-cloning is an anti-pattern. the As for the topic of the PR comment and |
@nitrocode changed the code to use |
Did some more testing (who needs sleep?), looks promising:
Will adjust tests tomorrow and mark this ready to review after that. |
Well, this looks actually pretty simple, this basically relies on the @GenPage there was no reason to have multiple dirs for workspace and even talking to Luke there was not a specific reason, my only guess was that at the time it made sense but since then Terraform has changed a lot and made available this new option but Atlantis never went back and improved upon. Technically PRs come from one repo and every PR will have a checkout/clone repo in atlantis datadir and that should suffice with any workflow that you run against the PR so having one dir for all the workspaces should not affect anything since the workspace switch is done by the TF binary. I think this makes Atlantis more closely matching a regular TF behavior than doing its own way of workspaces. |
Yeah, It would probably be more idempotent to use |
If the following directories were modified in the same PR branch and each directory had workspaces
Would this PR only clone once? Would it look like this?
|
@nitrocode In theory it should only clone once, but the problem is with the See: https://github.com/runatlantis/atlantis/blob/main/server/events/working_dir.go#L104-L125 There is bugs reported where if someone triggers commits too quickly with autoplan on it blows up as its trying to delete the repo before re-cloning. See https://atlantis-community.slack.com/archives/C5MGGAV0C/p1672846827664109 Also see #2952 |
Hi guys, I was going to finish this yesterday, but had some personal problems alongside work on another projects. I believe I can finish this later today after work.
One clone.
Yes, that's exactly what I had on my tests, but I think we should test this a lot just to make sure. @GenPage, I see that this bug is related, but maybe we can finish this PR and work on the |
e5cce59
to
7934fcc
Compare
Looks like the apply logic depends on this:
|
I like TF_DATA_DIR idea and this impl should be default. Just one question. When users use custom workflow plan stage which write same file, will parallel plan override each workspace files by this impl? If true, is it better to write document about it like |
@krrrr38 that's a good point. We'd need to ensure the plan file name contains the workspace name.
I do not understand this proposal. Could you explain it more?
@GenPage The way the workspace is set, either by the command line or by the TF_WORKSPACE env var, a file within the data dir is modified to contain the value of the workspace. If we did not use a separate data dir per workspace, parallel plans and applies would stomp over each other. By using a separate data for each workspace, we prevent that issue. |
$PLANFILE already contains workspace name, so no problem. I think users need to migrate file generation like global.tf.
This is a problem on parallel run. It might be ok to be well documented. (or this feature become plugable by user config like --working-dir-strategy) |
Thank you for confirming that.
Whether you use parallel run or not, you'd need to pass in the appropriate tfvars file for your workspace run. |
Has this PR been tested with locking in these scenarios?
Either way, the locking mechanism should not be affected by this change. 🙏 |
Hi @nitrocode, I didn't had time to look at locking yet, right now I'm still trying to figure out how to get the workspace on Before the code would get the workspace from the directory name and them it would use a regex to get the project name from the plan file, they are separated using a I will set this ready to review so you guys can have a look at the tests and maybe can help me how to solve this. For reference:
Edit: |
@@ -469,6 +469,7 @@ func (c *DefaultClient) prepCmd(log logging.SimpleLogging, v *version.Version, w | |||
fmt.Sprintf("WORKSPACE=%s", workspace), | |||
fmt.Sprintf("ATLANTIS_TERRAFORM_VERSION=%s", v.String()), | |||
fmt.Sprintf("DIR=%s", path), | |||
fmt.Sprintf("TF_DATA_DIR=.%s", workspace), |
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.
Before overwriting this env var, can we first check to see if the user supplied it in a custom workflow, and then if it's not set, then we can set it ourselves ?
We should have a test for this too to ensure we get the user provided TF_DATA_DIR
if one is set
example:
workflows:
default:
plan:
steps:
- env:
name: TF_DATA_DIR
command: 'echo ".terraform-$WORKSPACE-mydir"'
apply:
steps:
- env:
name: TF_DATA_DIR
command: 'echo ".terraform-$WORKSPACE-mydir"'
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.
In this scenario the user-provided environments override the TF_DATA_DIR
both on RunCommandAsync
and RunCommandWithVersion
since prepCmd
comes before than these on the call stack.
} | ||
|
||
// Remove TF_DATA_DIR for the workspace. | ||
os.RemoveAll(fmt.Sprintf("%s/%s/.terraform-%s", w.cloneDir(r, p), path, workspace)) |
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 hard coding this information, can we retrieve the exact TF_DATA_DIR
to remove?
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 does seem that we do not need to set up the TF_DATA_DIR at all since Terraform will set it up if a workspace is defined automatically so in that case we will not have a TF_DATA_DIR exposed, no?
I do not think the terraform binary will set this ENV variable when switching to a workspace in the shell context
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 TF_DATA_DIR
is not set, it defaults to .terraform
, if it is set, it can be pulled from the env value.
I'm suggesting, instead of assuming the data dir on this line, we should have a way of retrieving it programmatically rather than guessing the path.
If the user sets the TF_DATA_DIR for instance to something that does not match the above line, then this line will fail.
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.
Ok, I did some testing and we really need the TF_DATA_DIR
for parallel jobs.
But, it's not that easy to get the TF_DATA_DIR
for this function, this is executed on the atlantis unlock
command (and maybe in a few more places), so by the time we reach this function the TF_DATA_DIR
env is long gone.
Also the functions that have access to the final result of the TF_DATA_DIR
only return a string containing the output and are being called everywhere in the code, I can create a model to represent the result containing both the output and the TF_DATA_DIR
(and even more stuff related to the command result), but it will take me a few more days to adjust the code and the tests.
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.
Uff I see what you are saying, and yes that will be a bunch more work.
Take all the time you need Fabiano.
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 changed to draft based on this thread. Yes please take all the time you need since this is a big change. Thank you for your contribution here
@nitrocode looking at TF_DATA_DIR documentation I could not find anything that is workspace specific, so what prevent us from not changing TF_DATA_DIR at all? I think that if we just leave the default |
thanks Fabian for all your efforts.
…On Tue, Jan 24, 2023, 5:48 p.m. Fabiano Soares Honorato < ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In server/core/runtime/runtime.go
<#2921 (comment)>
:
> @@ -93,7 +94,7 @@ func GetPlanFilename(workspace string, projName string) string {
return fmt.Sprintf("%s.tfplan", workspace)
}
projName = strings.Replace(projName, "/", planfileSlashReplace, -1)
- return fmt.Sprintf("%s-%s.tfplan", projName, workspace)
+ return fmt.Sprintf("%s::%s.tfplan", projName, workspace)
Ok, tests adjusted, it was not easy, a lot of stuff seems to depend on the
pending_plan_finder, the code still not good enough though and I need to
validate more stuff before making sure everything is working.
—
Reply to this email directly, view it on GitHub
<#2921 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAQ3ERBFXW4GTBBFTZT6K6TWUCA6RANCNFSM6AAAAAATQ7MWAM>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
The TF_DATA_DIR is workspace specific. Here's an example.
For @jamengual workspace
For @Fabianoshz workspace
Since we want to do parallel plans and parallel applies for workspaces, we must have unique TF_DATA_DIR for each dir-workspace or parallel plans and applies will stomp over each other since each |
Hi @Fabianoshz any update on this PR ? We'd love to see this get implemented for the next release (0.24.0?). If you can, please test out your fork in your own setup for a while to make sure there are no issues. Please let us know. |
I will close this since updates have been stale for a long time. |
what
Ensure that we clone the repository only once per execution, this should reduce the amount of git clones.
why
tests
references