-
Notifications
You must be signed in to change notification settings - Fork 153
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
Implement QuickSyncPlan for k8s plugin #5020
Conversation
Signed-off-by: Shinnosuke Sawada <shin@warashi.dev>
// Clone implements deploysource.SourceCloner. | ||
func (c *Cloner) Clone(ctx context.Context, dest string) error { | ||
if _, err := git.RunGitCommand(ctx, c.gitPath, "", os.Environ(), "clone", c.remotePath, dest); err != nil { | ||
return err | ||
} | ||
if c.revision == "" { | ||
if _, err := git.RunGitCommand(ctx, c.gitPath, "", os.Environ(), "-C", dest, "checkout", c.revision); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} |
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 want to write tests for this method with git.faker.
However, the PR will become larger if I make git.faker public.
So, I decide not to write the test in this PR.
I'll make git.faker public later, and then write the test.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #5020 +/- ##
==========================================
- Coverage 22.45% 22.41% -0.04%
==========================================
Files 520 522 +2
Lines 56852 56915 +63
==========================================
- Hits 12766 12760 -6
- Misses 43060 43129 +69
Partials 1026 1026 ☔ View full report in Codecov by Sentry. |
Signed-off-by: Shinnosuke Sawada <shin@warashi.dev>
e18305f
to
2d03122
Compare
// Cloner is a source cloner for git repositories. | ||
type Cloner struct { | ||
gitPath string | ||
remotePath string | ||
revision string | ||
revisionName string | ||
} |
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.
@Warashi I have an idea with this sourcecloner package 🤔
Basically, our plan is to use the piped/deploysource
as the portal for all git resource operations (indeed, the name is deploysource and it emits the internal using git stub).
I think this newly created package sourcecloner
should follow that approach and more. What package dose is to fetch the already cloned source (prepared by deploysource), then I think we should emits the internal using git as same as we do in deploysource.
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 a Clone
interface, which could lead to confusion (if the reviewer doesn't know we don't clone or any, just fetch the cloned local source prepared by deploysource), how about to reuse the SourceCloner interface. aka this: https://github.com/pipe-cd/pipecd/blob/master/pkg/app/piped/deploysource/sourcecloner.go#L24-L28
I can see we have some implementation of this interface looks pretty fits our use case here:
https://github.com/pipe-cd/pipecd/blob/master/pkg/app/piped/deploysource/sourcecloner.go#L69-L94
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.
Oops, I missed the localSourceCloner. Thank you!
I think we can use this, but I wonder why this Clone
implementation only invokes the Copy method of the internal git repo.
If the internal git repo's current HEAD doesn't match localSourceCloner's revision, this Clone method will give the wrong results.
Or have I misunderstood the Revision()
of SourceCloner?
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.
@Warashi That's a good catch 👍 I think up to now, the localSourceCloner not yet raised any issues because its caller doesn't require any other revision than the HEAD 🤔 So, basically I think it's a bug potential logic and should be fixed, but as far as I investigated, the only place which we use this localSourceCloner is planpreview/builder
(ref: this code: https://github.com/pipe-cd/pipecd/blob/master/pkg/app/piped/planpreview/builder.go#L228), which basically only request for the HEAD of the current branch - due to the feature plan preview logic.
So, my point is to fix this localSourceCloner and use it for whatever "NOT git action pull directly but pull/fetch from a local source". WDYT? 🤔
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.
My point is: we should not create too many interfaces/packages that do similar tasks (in this case: clone source from git), or it will lead to confusion for the caller side. In this case, it would be better to have only one SourceCloner interface, one pull/fetch to the outer git, one pull/fetch to the local repo that was pulled by the previous implementation.
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 agree with you.
I'll fix the localSourceCloner and use it.
Signed-off-by: Shinnosuke Sawada-Dazai <shin@warashi.dev>
Signed-off-by: Shinnosuke Sawada-Dazai <shin@warashi.dev>
Signed-off-by: Shinnosuke Sawada-Dazai <shin@warashi.dev>
"github.com/pipe-cd/pipecd/pkg/plugin/api/v1alpha1/platform" | ||
) | ||
|
||
func GetPlanSourceCloner(input *platform.PlanPluginInput) (deploysource.SourceCloner, error) { |
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 wonder where we should place utilities like this function.
I place it here because all plugins may need this utility, but should I create another package under the plugin package?
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 got your point, let's find out later. In this PR, place it here is LGTM 👍
pkg/git/client.go
Outdated
@@ -252,6 +252,11 @@ func (c *client) envsForRepo(remote string) []string { | |||
return append(envs, c.gitEnvs...) | |||
} | |||
|
|||
// RunGitCommand runs a git command with the given arguments. |
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 don't use this anymore 👀
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.
Thank you. I removed it on this commit
355ce05
Signed-off-by: Shinnosuke Sawada-Dazai <shin@warashi.dev>
Signed-off-by: Shinnosuke Sawada-Dazai <shin@warashi.dev>
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.
LGTM with some nits, thank you 🚀
(we can fix nits with other PRs)
d, err := os.MkdirTemp("", "") // TODO | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to prepare temporary directory (%w)", err) | ||
} | ||
defer os.RemoveAll(d) |
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.
@Warashi Question:
Should we add workingDir as PlanPluginInput? 🤔 Currently, the planner in the controller uses workingDir passed at the time controller.planner object is created, which mean we have 1:1 for relationship between workingDir & planner which is used to build plan for a deployment
ref:
pipecd/pkg/app/piped/controller/controller.go
Lines 438 to 443 in 6400c89
// Ensure the existence of the working directory for the deployment. | |
workingDir, err := os.MkdirTemp(c.workspaceDir, d.Id+"-planner-*") | |
if err != nil { | |
logger.Error("failed to create working directory for planner", zap.Error(err)) | |
return nil, err | |
} |
message PlanPluginInput { |
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 make it that way, then the piped.planner object will create the workingDir then clone/pull the deploy source, then we pass the workingDir (which contains cloned source) to the planner plugin via PlanPluginInput.
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.
That sounds nice.
In this PR, we clone the deploy source manually.
However, it's needed for each plugin implementation, so it's simpler if we handle it at piped and only use the prepared source in the plugin.
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, let address it by another PR 👍
if err != nil { | ||
return nil, err | ||
} | ||
|
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.
nits
cfg := ds.ApplicationConfig.KubernetesApplicationSpec
if cfg == nil {
return nil, fmt.Errorf("missing KubernetesApplicationSpec in application configuration")
}
Should check spec available to avoid nil pointer 👀
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 fixed it on this commit.
d845f7a
autoRollback := false | ||
if a := ds.ApplicationConfig.KubernetesApplicationSpec.Input.AutoRollback; a != nil { | ||
autoRollback = *a | ||
} |
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.
nits, we have a default value set as true, so no need to initialize autoRollback var as false here, since the ds.ApplicationConfig.KubernetesApplicationSpec.Input.AutoRollback
is true as init
ref: ds.ApplicationConfig.KubernetesApplicationSpec.Input.AutoRollback
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.
Thank you.
I noticed that I can view the document here.
https://pkg.go.dev/github.com/pipe-cd/pipecd/pkg/config#KubernetesDeploymentInput
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 fixed it on this commit.
d845f7a
Signed-off-by: Shinnosuke Sawada-Dazai <shin@warashi.dev>
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.
🚀
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.
👍👍
* Implement QuickSyncPlan for k8s plugin Signed-off-by: Shinnosuke Sawada <shin@warashi.dev> * Fix build and add TODO comment Signed-off-by: Shinnosuke Sawada <shin@warashi.dev> * Use deploysource.NewLocalSourceCloner to clone source code Signed-off-by: Shinnosuke Sawada-Dazai <shin@warashi.dev> * Fix localSourceCloner.Clone to checkout target revision Signed-off-by: Shinnosuke Sawada-Dazai <shin@warashi.dev> * Format sources Signed-off-by: Shinnosuke Sawada-Dazai <shin@warashi.dev> * Remove unused function Signed-off-by: Shinnosuke Sawada-Dazai <shin@warashi.dev> * Add licence Signed-off-by: Shinnosuke Sawada-Dazai <shin@warashi.dev> * Fix kubernetes application spec nil checks Signed-off-by: Shinnosuke Sawada-Dazai <shin@warashi.dev> --------- Signed-off-by: Shinnosuke Sawada <shin@warashi.dev> Signed-off-by: Shinnosuke Sawada-Dazai <shin@warashi.dev> Signed-off-by: khanhtc1202 <khanhtc1202@gmail.com>
What this PR does / why we need it:
This PR implements QuickSyncPlan RPC for the Kubernetes plugin.
Which issue(s) this PR fixes:
Part of #4980
Does this PR introduce a user-facing change?: