Skip to content

Commit

Permalink
Make both clone and push depend on the git impl
Browse files Browse the repository at this point in the history
This follows up the stage-setting in prior commits, by respecting the
GitImplementation field given in the GitRepository object. NB it only
matters for cloning and pushing, so gogit is used in the "middle" to
record the commit in the local checkout.

Signed-off-by: Michael Bridgen <michael@weave.works>
  • Loading branch information
squaremo authored and hiddeco committed Jan 14, 2021
1 parent 6866f98 commit 4fde199
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 75 deletions.
35 changes: 24 additions & 11 deletions controllers/imageupdateautomation_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(ctx context.Context, req ctr
}

var repo *gogit.Repository
if repo, err = cloneInto(ctx, access, auto.Spec.Checkout.Branch, tmp); err != nil {
if repo, err = cloneInto(ctx, access, auto.Spec.Checkout.Branch, tmp, origin.Spec.GitImplementation); err != nil {
return failWithError(err)
}

Expand Down Expand Up @@ -210,7 +210,7 @@ func (r *ImageUpdateAutomationReconciler) Reconcile(ctx context.Context, req ctr
return failWithError(err)
}
} else {
if err := push(ctx, tmp, auto.Spec.Checkout.Branch, access); err != nil {
if err := push(ctx, tmp, repo, auto.Spec.Checkout.Branch, access, origin.Spec.GitImplementation); err != nil {
return failWithError(err)
}

Expand Down Expand Up @@ -329,12 +329,14 @@ func (r *ImageUpdateAutomationReconciler) getRepoAccess(ctx context.Context, rep
return access, nil
}

func cloneInto(ctx context.Context, access repoAccess, branch, path string) (*gogit.Repository, error) {
// FIXME this just arbitrarily uses libgit2, so I can see whether
// it works
// cloneInto clones the upstream repository at the `branch` given,
// using the git library indicated by `impl`. It returns a
// `*gogit.Repository` regardless of the git library, since that is
// used for committing changes.
func cloneInto(ctx context.Context, access repoAccess, branch, path, impl string) (*gogit.Repository, error) {
checkoutStrat, err := git.CheckoutStrategyForRef(&sourcev1.GitRepositoryRef{
Branch: branch,
}, sourcev1.LibGit2Implementation)
}, impl)
if err == nil {
_, _, err = checkoutStrat.Checkout(ctx, path, access.url, access.auth)
}
Expand Down Expand Up @@ -388,12 +390,23 @@ func commitAll(ctx context.Context, repo *gogit.Repository, commit *imagev1.Comm
return rev.String(), nil
}

func push(ctx context.Context, path, branch string, access repoAccess) error {
lg2repo, err := libgit2.OpenRepository(path)
if err != nil {
return err
// push pushes the branch given to the origin using the git library
// indicated by `impl`. It's passed both the path to the repo and a
// gogit.Repository value, since the latter may as well be used if the
// implementation is GoGit.
func push(ctx context.Context, path string, repo *gogit.Repository, branch string, access repoAccess, impl string) error {
switch impl {
case sourcev1.LibGit2Implementation:
lg2repo, err := libgit2.OpenRepository(path)
if err != nil {
return err
}
return pushLibgit2(lg2repo, access, branch)
case sourcev1.GoGitImplementation:
return pushGoGit(ctx, repo, access)
default:
return fmt.Errorf("unknown git implementation %q", impl)
}
return pushLibgit2(lg2repo, access, branch)
}

func pushGoGit(ctx context.Context, repo *gogit.Repository, access repoAccess) error {
Expand Down
105 changes: 41 additions & 64 deletions controllers/update_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,12 @@ func randStringRunes(n int) string {

var _ = Describe("ImageUpdateAutomation", func() {
var (
impl string
branch string
repositoryPath string
repoURL string
namespace *corev1.Namespace
gitServer *gittestserver.GitServer
gitRepoKey types.NamespacedName
commitMessage string
)

// Start the git server
Expand All @@ -94,40 +93,24 @@ var _ = Describe("ImageUpdateAutomation", func() {
Expect(gitServer.StartHTTP()).To(Succeed())

repoURL = gitServer.HTTPAddress() + repositoryPath

gitRepoKey = types.NamespacedName{
Name: "image-auto-" + randStringRunes(5),
Namespace: namespace.Name,
}

gitRepo := &sourcev1.GitRepository{
ObjectMeta: metav1.ObjectMeta{
Name: gitRepoKey.Name,
Namespace: namespace.Name,
},
Spec: sourcev1.GitRepositorySpec{
URL: repoURL,
Interval: metav1.Duration{Duration: time.Minute},
},
}
Expect(k8sClient.Create(context.Background(), gitRepo)).To(Succeed())
})

AfterEach(func() {
gitServer.StopHTTP()
os.RemoveAll(gitServer.Root())
Expect(k8sClient.Delete(context.Background(), namespace)).To(Succeed())
})

It("Initialises git OK", func() {
Expect(initGitRepo(gitServer, "testdata/appconfig", branch, repositoryPath)).To(Succeed())
})

Context("with ImagePolicy", func() {
withImagePolicy := func() {
var (
localRepo *git.Repository
policy *imagev1_reflect.ImagePolicy
policyKey types.NamespacedName
localRepo *git.Repository
policy *imagev1_reflect.ImagePolicy
policyKey types.NamespacedName
gitRepoKey types.NamespacedName
commitMessage string
)

const latestImage = "helloworld:1.0.1"
Expand All @@ -146,6 +129,24 @@ var _ = Describe("ImageUpdateAutomation", func() {
})
Expect(err).ToNot(HaveOccurred())

gitRepoKey = types.NamespacedName{
Name: "image-auto-" + randStringRunes(5),
Namespace: namespace.Name,
}

gitRepo := &sourcev1.GitRepository{
ObjectMeta: metav1.ObjectMeta{
Name: gitRepoKey.Name,
Namespace: namespace.Name,
},
Spec: sourcev1.GitRepositorySpec{
URL: repoURL,
Interval: metav1.Duration{Duration: time.Minute},
GitImplementation: impl,
},
}
Expect(k8sClient.Create(context.Background(), gitRepo)).To(Succeed())

policyKey = types.NamespacedName{
Name: "policy-" + randStringRunes(5),
Namespace: namespace.Name,
Expand Down Expand Up @@ -177,6 +178,7 @@ var _ = Describe("ImageUpdateAutomation", func() {
})

AfterEach(func() {
Expect(k8sClient.Delete(context.Background(), namespace)).To(Succeed())
Expect(k8sClient.Delete(context.Background(), policy)).To(Succeed())
})

Expand Down Expand Up @@ -289,51 +291,26 @@ var _ = Describe("ImageUpdateAutomation", func() {
// the annotation and make sure it runs again.
Expect(k8sClient.Get(context.Background(), updateKey, updateBySetters)).To(Succeed())
Expect(updateBySetters.Status.LastAutomationRunTime).ToNot(BeNil())
lastRunTime := updateBySetters.Status.LastAutomationRunTime.Time

commitInRepo(repoURL, branch, "Revert image update", func(tmp string) {
// revert the change made by copying the old version
// of the file back over then restoring the setter
// marker
copy.Copy("testdata/appconfig/deploy.yaml", filepath.Join(tmp, "deploy.yaml"))
replaceMarker(tmp, policyKey)
})
// check that it was reverted correctly
compareRepoWithExpected(repoURL, branch, "testdata/appconfig", func(tmp string) {
replaceMarker(tmp, policyKey)
})

ts := time.Now().String()
var updatePatch imagev1.ImageUpdateAutomation
updatePatch.Spec = updateBySetters.Spec // otherwise the patch will blank some fields
updatePatch.Name = updateKey.Name
updatePatch.Namespace = updateKey.Namespace
updatePatch.ObjectMeta.Annotations = map[string]string{
meta.ReconcileRequestAnnotation: ts,
}
Expect(k8sClient.Patch(context.Background(), &updatePatch, client.Merge)).To(Succeed())
})
})
}

// ... this is where the reconciler is supposed to do its work ...
Context("Using go-git", func() {
BeforeEach(func() {
impl = sourcev1.GoGitImplementation
})

var newUpdate imagev1.ImageUpdateAutomation
Eventually(func() bool {
if err := k8sClient.Get(context.Background(), updateKey, &newUpdate); err != nil {
return false
}
newLastRun := newUpdate.Status.LastAutomationRunTime
return newLastRun != nil && newLastRun.Time.After(lastRunTime)
}, timeout, time.Second).Should(BeTrue())
// check that the annotation was recorded as seen
Expect(newUpdate.Status.LastHandledReconcileAt).To(Equal(ts))
expectCommittedAndPushed(newUpdate.Status.Conditions)
Context("with image policy", withImagePolicy)
})

// check that a new commit was made
compareRepoWithExpected(repoURL, branch, "testdata/appconfig-setters-expected", func(tmp string) {
replaceMarker(tmp, policyKey)
})
})
Context("Using libgit2", func() {
BeforeEach(func() {
impl = sourcev1.LibGit2Implementation
})

Context("with image policy", withImagePolicy)
})

})

func expectCommittedAndPushed(conditions []metav1.Condition) {
Expand Down

0 comments on commit 4fde199

Please sign in to comment.