From 5a74ebf9d8d861b89e9c3161f67e2774daa29f98 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Tue, 11 Jun 2019 15:30:09 +0200 Subject: [PATCH] *: remove agola git hook * Delete the command and it's rule in the Makefile * Don't use it inside gitserver and remove related config option (also from examples) * Remove webhook parsing from agolagit gitsource --- Makefile | 6 +- cmd/agola-git-hook/main.go | 165 ---------------------- examples/agolademo/config.yml | 1 - examples/kubernetes/distributed/agola.yml | 1 - examples/kubernetes/simple/agola.yml | 1 - internal/gitsources/agolagit/agolagit.go | 5 + internal/gitsources/agolagit/parse.go | 142 ------------------- internal/gitsources/agolagit/types.go | 140 ------------------ internal/services/config/config.go | 6 +- internal/services/gitserver/main.go | 43 +----- 10 files changed, 8 insertions(+), 502 deletions(-) delete mode 100644 cmd/agola-git-hook/main.go delete mode 100644 internal/gitsources/agolagit/parse.go delete mode 100644 internal/gitsources/agolagit/types.go diff --git a/Makefile b/Makefile index 5d215e8..e1e3349 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ TOOLBOX_ARCHS=amd64 arm64 all: build .PHONY: build -build: agola agola-toolbox agola-git-hook +build: agola agola-toolbox .PHONY: test test: gocovmerge @@ -57,10 +57,6 @@ agola-toolbox: go-bindata: GOBIN=$(PROJDIR)/tools/bin go install github.com/go-bindata/go-bindata/go-bindata -.PHONY: agola-git-hook -agola-git-hook: - CGO_ENABLED=0 GO111MODULE=on go build $(if $(AGOLA_TAGS),-tags "$(AGOLA_TAGS)") -ldflags $(LD_FLAGS) -o $(PROJDIR)/bin/agola-git-hook $(REPO_PATH)/cmd/agola-git-hook - .PHONY: gocovmerge gocovmerge: GOBIN=$(PROJDIR)/tools/bin go install github.com/wadey/gocovmerge diff --git a/cmd/agola-git-hook/main.go b/cmd/agola-git-hook/main.go deleted file mode 100644 index f975b4d..0000000 --- a/cmd/agola-git-hook/main.go +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright 2019 Sorint.lab -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied -// See the License for the specific language governing permissions and -// limitations under the License. -package main - -import ( - "bytes" - "context" - "encoding/json" - "log" - "net/http" - "os" - "strings" - - "github.com/sorintlab/agola/internal/util" -) - -const ( - emptySHA = "0000000000000000000000000000000000000000" -) - -type Hook struct { - Sha string `json:"sha"` - Ref string `json:"ref"` - Before string `json:"before"` - After string `json:"after"` - Compare string `json:"compare_url"` - RefType string `json:"ref_type"` - - Pusher struct { - Name string `json:"name"` - Email string `json:"email"` - Login string `json:"login"` - Username string `json:"username"` - } `json:"pusher"` - - Repo struct { - ID int64 `json:"id"` - Name string `json:"name"` - FullName string `json:"full_name"` - URL string `json:"html_url"` - Private bool `json:"private"` - Owner struct { - Name string `json:"name"` - Email string `json:"email"` - Username string `json:"username"` - } `json:"owner"` - } `json:"repository"` - - Commits []Commit `json:"commits"` - - Sender struct { - ID int64 `json:"id"` - Login string `json:"login"` - Username string `json:"username"` - Email string `json:"email"` - Avatar string `json:"avatar_url"` - } `json:"sender"` -} - -type Commit struct { - ID string `json:"id"` - Message string `json:"message"` - URL string `json:"url"` -} - -func isBareRepository(path string) (bool, error) { - git := &util.Git{} - out, err := git.Output(context.Background(), nil, "rev-parse", "--is-bare-repository") - if err != nil { - return false, err - } - return string(out) == "true", nil -} - -func commitMessage(sha string) (string, error) { - git := &util.Git{} - out, err := git.Output(context.Background(), nil, "show", "-s", "--format=%B", sha) - return strings.TrimSpace(string(out)), err -} - -func genHook(oldCommit, newCommit, ref string) (*Hook, error) { - hook := &Hook{} - - hook.Before = oldCommit - hook.After = newCommit - hook.Ref = ref - - hook.Commits = make([]Commit, 2) - - hook.Commits[0].ID = newCommit - hook.Commits[1].ID = oldCommit - - newCommitMessage, err := commitMessage(newCommit) - if err != nil { - return nil, err - } - hook.Commits[0].Message = newCommitMessage - if oldCommit != emptySHA { - oldCommitMessage, err := commitMessage(oldCommit) - if err != nil { - return nil, err - } - hook.Commits[1].Message = oldCommitMessage - } - - git := &util.Git{} - repo, _ := git.ConfigGet(context.Background(), "agola.repo") - log.Printf("repo: %s", repo) - parts := strings.Split(string(repo), "/") - - hook.Repo.Owner.Username = parts[0] - hook.Repo.Name = parts[1] - - return hook, nil -} - -func main() { - log.Printf("post receice hook") - - //data, _ := ioutil.ReadAll(os.Stdin) - //parts := strings.Split(string(data), " ") - //if len(parts) != 3 { - // log.Fatalf("not enought parts. data: %s", data) - //} - - //oldCommit := parts[0] - //newCommit := parts[1] - //ref := parts[2] - - oldCommit := os.Args[1] - newCommit := os.Args[2] - ref := os.Args[3] - - log.Printf("oldcommit: %s, newcommit: %s, ref: %s", oldCommit, newCommit, ref) - - git := &util.Git{} - repo, _ := git.ConfigGet(context.Background(), "agola.repo") - webhookURL, _ := git.ConfigGet(context.Background(), "agola.webhookURL") - log.Printf("repo: %s", repo) - log.Printf("webhookURL: %s", webhookURL) - - hook, _ := genHook(oldCommit, newCommit, ref) - hookj, _ := json.Marshal(hook) - - req, err := http.NewRequest("POST", webhookURL, bytes.NewReader(hookj)) - if err != nil { - log.Fatalf("err: %v", err) - } - req.Header.Set("Content-Type", "application/json") - req.Header.Set("X-Gitea-Event", "push") - if _, err := http.DefaultClient.Do(req); err != nil { - log.Fatalf("err: %v", err) - } -} diff --git a/examples/agolademo/config.yml b/examples/agolademo/config.yml index af2caec..94bd8f7 100644 --- a/examples/agolademo/config.yml +++ b/examples/agolademo/config.yml @@ -61,7 +61,6 @@ executor: gitserver: dataDir: /tmp/agola/gitserver - githookPath: ./bin/agola-git-hook gatewayURL: "http://localhost:8000" web: listenAddress: ":4003" \ No newline at end of file diff --git a/examples/kubernetes/distributed/agola.yml b/examples/kubernetes/distributed/agola.yml index 7d27eba..634d540 100644 --- a/examples/kubernetes/distributed/agola.yml +++ b/examples/kubernetes/distributed/agola.yml @@ -139,7 +139,6 @@ data: gitserver: dataDir: /mnt/agola/local/gitserver - githookPath: ./bin/agola-git-hook gatewayURL: "http://agola-gateway:8000" web: listenAddress: ":4003" diff --git a/examples/kubernetes/simple/agola.yml b/examples/kubernetes/simple/agola.yml index e939f48..8ecd20f 100644 --- a/examples/kubernetes/simple/agola.yml +++ b/examples/kubernetes/simple/agola.yml @@ -128,7 +128,6 @@ data: gitserver: dataDir: /mnt/agola/local/gitserver - githookPath: ./bin/agola-git-hook gatewayURL: "http://agola-internal:8000" web: listenAddress: ":4003" diff --git a/internal/gitsources/agolagit/agolagit.go b/internal/gitsources/agolagit/agolagit.go index 130cb2f..16a74a7 100644 --- a/internal/gitsources/agolagit/agolagit.go +++ b/internal/gitsources/agolagit/agolagit.go @@ -27,6 +27,7 @@ import ( "time" gitsource "github.com/sorintlab/agola/internal/gitsources" + "github.com/sorintlab/agola/internal/services/types" errors "golang.org/x/xerrors" ) @@ -160,6 +161,10 @@ func (c *Client) CreateRepoWebhook(repopath, url, secret string) error { return nil } +func (c *Client) ParseWebhook(r *http.Request, secret string) (*types.WebhookData, error) { + return nil, nil +} + func (c *Client) DeleteRepoWebhook(repopath, u string) error { return nil } diff --git a/internal/gitsources/agolagit/parse.go b/internal/gitsources/agolagit/parse.go deleted file mode 100644 index 2db1392..0000000 --- a/internal/gitsources/agolagit/parse.go +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright 2019 Sorint.lab -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied -// See the License for the specific language governing permissions and -// limitations under the License. - -package agolagit - -import ( - "encoding/json" - "fmt" - "io" - "io/ioutil" - "net/http" - "path" - "strconv" - "strings" - - "github.com/sorintlab/agola/internal/services/types" - - errors "golang.org/x/xerrors" -) - -const ( - hookEvent = "X-Gitea-Event" - - hookPush = "push" - hookPullRequest = "pull_request" - - prStateOpen = "open" - - prActionOpen = "opened" - prActionSync = "synchronized" -) - -func (c *Client) ParseWebhook(r *http.Request, secret string) (*types.WebhookData, error) { - data, err := ioutil.ReadAll(io.LimitReader(r.Body, 10*1024*1024)) - if err != nil { - return nil, err - } - - switch r.Header.Get(hookEvent) { - case hookPush: - return parsePushHook(data) - case hookPullRequest: - return parsePullRequestHook(data) - default: - return nil, errors.Errorf("unknown webhook event type: %q", r.Header.Get(hookEvent)) - } -} - -func parsePushHook(data []byte) (*types.WebhookData, error) { - push := new(pushHook) - err := json.Unmarshal(data, push) - if err != nil { - return nil, err - } - - return webhookDataFromPush(push) -} - -func parsePullRequestHook(data []byte) (*types.WebhookData, error) { - prhook := new(pullRequestHook) - err := json.Unmarshal(data, prhook) - if err != nil { - return nil, err - } - - // skip non open pull requests - if prhook.PullRequest.State != prStateOpen { - return nil, nil - } - // only accept actions that have new commits - if prhook.Action != prActionOpen && prhook.Action != prActionSync { - return nil, nil - } - - return webhookDataFromPullRequest(prhook), nil -} - -func webhookDataFromPush(hook *pushHook) (*types.WebhookData, error) { - sender := hook.Sender.Username - if sender == "" { - sender = hook.Sender.Login - } - - // common data - whd := &types.WebhookData{ - CommitSHA: hook.After, - Ref: hook.Ref, - CompareLink: hook.Compare, - CommitLink: fmt.Sprintf("%s/commit/%s", hook.Repo.URL, hook.After), - Sender: sender, - - Repo: types.WebhookDataRepo{ - Path: path.Join(hook.Repo.Owner.Username, hook.Repo.Name), - WebURL: hook.Repo.URL, - }, - } - - whd.Event = types.WebhookEventPush - whd.Branch = strings.TrimPrefix(hook.Ref, "refs/heads/") - whd.BranchLink = fmt.Sprintf("%s/src/branch/%s", hook.Repo.URL, whd.Branch) - if len(hook.Commits) > 0 { - whd.Message = hook.Commits[0].Message - } - - return whd, nil -} - -// helper function that extracts the Build data from a Gitea pull_request hook -func webhookDataFromPullRequest(hook *pullRequestHook) *types.WebhookData { - sender := hook.Sender.Username - if sender == "" { - sender = hook.Sender.Login - } - build := &types.WebhookData{ - Event: types.WebhookEventPullRequest, - CommitSHA: hook.PullRequest.Head.Sha, - Ref: fmt.Sprintf("refs/pull/%d/head", hook.Number), - CommitLink: fmt.Sprintf("%s/commit/%s", hook.Repo.URL, hook.PullRequest.Head.Sha), - Branch: hook.PullRequest.Base.Ref, - Message: hook.PullRequest.Title, - Sender: sender, - PullRequestID: strconv.FormatInt(hook.PullRequest.ID, 10), - PullRequestLink: hook.PullRequest.URL, - - Repo: types.WebhookDataRepo{ - Path: path.Join(hook.Repo.Owner.Username, hook.Repo.Name), - WebURL: hook.Repo.URL, - }, - } - return build -} diff --git a/internal/gitsources/agolagit/types.go b/internal/gitsources/agolagit/types.go deleted file mode 100644 index 6cb8e67..0000000 --- a/internal/gitsources/agolagit/types.go +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2019 Sorint.lab -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied -// See the License for the specific language governing permissions and -// limitations under the License. - -package agolagit - -type pushHook struct { - Sha string `json:"sha"` - Ref string `json:"ref"` - Before string `json:"before"` - After string `json:"after"` - Compare string `json:"compare_url"` - RefType string `json:"ref_type"` - - Pusher struct { - Name string `json:"name"` - Email string `json:"email"` - Login string `json:"login"` - Username string `json:"username"` - } `json:"pusher"` - - Repo struct { - ID int64 `json:"id"` - Name string `json:"name"` - FullName string `json:"full_name"` - URL string `json:"html_url"` - Private bool `json:"private"` - Owner struct { - Name string `json:"name"` - Email string `json:"email"` - Username string `json:"username"` - } `json:"owner"` - } `json:"repository"` - - Commits []struct { - ID string `json:"id"` - Message string `json:"message"` - URL string `json:"url"` - } `json:"commits"` - - Sender struct { - ID int64 `json:"id"` - Login string `json:"login"` - Username string `json:"username"` - Email string `json:"email"` - Avatar string `json:"avatar_url"` - } `json:"sender"` -} - -type pullRequestHook struct { - Action string `json:"action"` - Number int64 `json:"number"` - PullRequest struct { - ID int64 `json:"id"` - User struct { - ID int64 `json:"id"` - Username string `json:"username"` - Name string `json:"full_name"` - Email string `json:"email"` - Avatar string `json:"avatar_url"` - } `json:"user"` - Title string `json:"title"` - Body string `json:"body"` - State string `json:"state"` - URL string `json:"html_url"` - Mergeable bool `json:"mergeable"` - Merged bool `json:"merged"` - MergeBase string `json:"merge_base"` - Base struct { - Label string `json:"label"` - Ref string `json:"ref"` - Sha string `json:"sha"` - Repo struct { - ID int64 `json:"id"` - Name string `json:"name"` - FullName string `json:"full_name"` - URL string `json:"html_url"` - Private bool `json:"private"` - Owner struct { - ID int64 `json:"id"` - Username string `json:"username"` - Name string `json:"full_name"` - Email string `json:"email"` - Avatar string `json:"avatar_url"` - } `json:"owner"` - } `json:"repo"` - } `json:"base"` - Head struct { - Label string `json:"label"` - Ref string `json:"ref"` - Sha string `json:"sha"` - Repo struct { - ID int64 `json:"id"` - Name string `json:"name"` - FullName string `json:"full_name"` - URL string `json:"html_url"` - Private bool `json:"private"` - Owner struct { - ID int64 `json:"id"` - Username string `json:"username"` - Name string `json:"full_name"` - Email string `json:"email"` - Avatar string `json:"avatar_url"` - } `json:"owner"` - } `json:"repo"` - } `json:"head"` - } `json:"pull_request"` - Repo struct { - ID int64 `json:"id"` - Name string `json:"name"` - FullName string `json:"full_name"` - URL string `json:"html_url"` - Private bool `json:"private"` - Owner struct { - ID int64 `json:"id"` - Username string `json:"username"` - Name string `json:"full_name"` - Email string `json:"email"` - Avatar string `json:"avatar_url"` - } `json:"owner"` - } `json:"repository"` - Sender struct { - ID int64 `json:"id"` - Login string `json:"login"` - Username string `json:"username"` - Name string `json:"full_name"` - Email string `json:"email"` - Avatar string `json:"avatar_url"` - } `json:"sender"` -} diff --git a/internal/services/config/config.go b/internal/services/config/config.go index bc3d11b..a50d751 100644 --- a/internal/services/config/config.go +++ b/internal/services/config/config.go @@ -127,8 +127,7 @@ type Gitserver struct { DataDir string `yaml:"dataDir"` - GithookPath string `yaml:"githookPath"` - GatewayURL string `yaml:"gatewayURL"` + GatewayURL string `yaml:"gatewayURL"` Web Web `yaml:"web"` Etcd Etcd `yaml:"etcd"` @@ -343,9 +342,6 @@ func Validate(c *Config) error { if c.Gitserver.DataDir == "" { return errors.Errorf("git server dataDir is empty") } - if c.Gitserver.GithookPath == "" { - return errors.Errorf("git server githookPath is empty") - } if c.Gitserver.GatewayURL == "" { return errors.Errorf("git server gatewayURL is empty") } diff --git a/internal/services/gitserver/main.go b/internal/services/gitserver/main.go index d4ecdb3..82549e6 100644 --- a/internal/services/gitserver/main.go +++ b/internal/services/gitserver/main.go @@ -19,7 +19,6 @@ import ( "crypto/tls" "net/http" "os" - "os/exec" "path/filepath" "regexp" "strings" @@ -127,33 +126,6 @@ func Matcher(matchRegexp *regexp.Regexp) mux.MatcherFunc { } } -func (s *Gitserver) repoPostCreateFunc(githookPath, gatewayURL string) handlers.RepoPostCreateFunc { - return func(repoPath, repoAbsPath string) error { - f, err := os.OpenFile(filepath.Join(repoAbsPath, "hooks/post-receive"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0760) - if err != nil { - return err - } - defer f.Close() - log.Infof("creating post-receive hook: %s", repoAbsPath) - f.WriteString("#/bin/bash\n") - f.WriteString("while read oval nval ref; do\n") - f.WriteString(githookPath + " $oval $nval $ref\n") - f.WriteString("done\n") - - parts := strings.Split(string(repoPath), "/") - if len(parts) != 2 { - return errors.Errorf("wrong repo path: %q", repoPath) - } - userID := parts[0] - - git := &util.Git{GitDir: repoAbsPath} - git.ConfigSet(context.Background(), "agola.repo", repoPath) - git.ConfigSet(context.Background(), "agola.webhookURL", gatewayURL+"/webhooks?userid="+userID) - - return nil - } -} - type Gitserver struct { c *config.Gitserver } @@ -163,26 +135,13 @@ func NewGitserver(c *config.Gitserver) (*Gitserver, error) { level.SetLevel(zapcore.DebugLevel) } - var err error - c.GithookPath, err = filepath.Abs(c.GithookPath) - if err != nil { - return nil, errors.Errorf("cannot find agola-git-hook absolute path: %w", err) - } - if c.GithookPath == "" { - path, err := exec.LookPath("agola-git-hook") - if err != nil { - return nil, errors.Errorf("cannot find \"agola-git-hook\" binaries in PATH, agola-githook path must be explicitly provided") - } - c.GithookPath = path - } - return &Gitserver{ c: c, }, nil } func (s *Gitserver) Run(ctx context.Context) error { - gitSmartHandler := handlers.NewGitSmartHandler(logger, s.c.DataDir, true, repoAbsPath, s.repoPostCreateFunc(s.c.GithookPath, s.c.GatewayURL)) + gitSmartHandler := handlers.NewGitSmartHandler(logger, s.c.DataDir, true, repoAbsPath, nil) fetchFileHandler := handlers.NewFetchFileHandler(logger, s.c.DataDir, repoAbsPath) router := mux.NewRouter()