Skip to content

Commit

Permalink
feat: add gracefull shutdown - RK-19184 (#84)
Browse files Browse the repository at this point in the history
* feat: add gracefull shutdown

Signed-off-by: Gosha <[email protected]>

* feat: add logs

Signed-off-by: Gosha <[email protected]>

* fix: update git signture in tests

Signed-off-by: Gosha <[email protected]>

---------

Signed-off-by: Gosha <[email protected]>
  • Loading branch information
gosharo authored Jul 8, 2023
1 parent 78577e0 commit dcd514c
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 26 deletions.
10 changes: 0 additions & 10 deletions cmd/piper/piper.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,5 @@ func main() {
Workflows: workflows,
}

err = globalClients.GitProvider.SetWebhook()
if err != nil {
panic(err)
}

//err = common.Git.UnsetWebhook()
//if err != nil {
// panic(err)
//}

server.Start(cfg, globalClients)
}
25 changes: 13 additions & 12 deletions pkg/git_provider/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,22 +100,20 @@ func (c *GithubClientImpl) GetFiles(ctx *context.Context, repo string, branch st
}

func (c *GithubClientImpl) SetWebhook() error {
// TODO: validate secret
ctx := context.Background()
hook := &github.Hook{
Config: map[string]interface{}{
"url": c.cfg.GitProviderConfig.WebhookURL,
"content_type": "json",
"secret": c.cfg.GitProviderConfig.WebhookSecret, // TODO webhook from k8s secret

"secret": c.cfg.GitProviderConfig.WebhookSecret,
},
Events: []string{"push", "pull_request"},
Active: github.Bool(true),
}
if c.cfg.GitProviderConfig.OrgLevelWebhook {
respHook, ok := isOrgWebhookEnabled(ctx, c)
if !ok {
retHook, resp, err := c.client.Organizations.CreateHook(
createdHook, resp, err := c.client.Organizations.CreateHook(
ctx,
c.cfg.GitProviderConfig.OrgName,
hook,
Expand All @@ -126,7 +124,8 @@ func (c *GithubClientImpl) SetWebhook() error {
if resp.StatusCode != 201 {
return fmt.Errorf("failed to create org level webhhok, API returned %d", resp.StatusCode)
}
c.hooks = append(c.hooks, retHook)
log.Printf("edited webhook of type %s for %s :%s\n", createdHook.GetType(), c.cfg.GitProviderConfig.OrgName, createdHook.GetURL())
c.hooks = append(c.hooks, createdHook)
} else {
updatedHook, resp, err := c.client.Organizations.EditHook(
ctx,
Expand All @@ -144,6 +143,7 @@ func (c *GithubClientImpl) SetWebhook() error {
resp.StatusCode,
)
}
log.Printf("edited webhook of type %s for %s :%s\n", updatedHook.GetType(), c.cfg.GitProviderConfig.OrgName, updatedHook.GetURL())
c.hooks = append(c.hooks, updatedHook)
}

Expand All @@ -152,15 +152,16 @@ func (c *GithubClientImpl) SetWebhook() error {
for _, repo := range strings.Split(c.cfg.GitProviderConfig.RepoList, ",") {
respHook, ok := isRepoWebhookEnabled(ctx, c, repo)
if !ok {
_, resp, err := c.client.Repositories.CreateHook(ctx, c.cfg.GitProviderConfig.OrgName, repo, hook)
createdHook, resp, err := c.client.Repositories.CreateHook(ctx, c.cfg.GitProviderConfig.OrgName, repo, hook)
if err != nil {
return err
}

if resp.StatusCode != 201 {
return fmt.Errorf("failed to create repo level webhhok for %s, API returned %d", repo, resp.StatusCode)
}
c.hooks = append(c.hooks, hook)
log.Printf("created webhook of type %s for %s :%s\n", createdHook.GetType(), repo, createdHook.GetURL())
c.hooks = append(c.hooks, createdHook)
} else {
updatedHook, resp, err := c.client.Repositories.EditHook(ctx, c.cfg.GitProviderConfig.OrgName, repo, respHook.GetID(), hook)
if err != nil {
Expand All @@ -169,7 +170,7 @@ func (c *GithubClientImpl) SetWebhook() error {
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to update repo level webhhok for %s, API returned %d", repo, resp.StatusCode)
}

log.Printf("edited webhook of type %s for %s :%s\n", updatedHook.GetType(), repo, updatedHook.GetURL())
c.hooks = append(c.hooks, updatedHook)
}
}
Expand All @@ -178,13 +179,12 @@ func (c *GithubClientImpl) SetWebhook() error {
return nil
}

func (c *GithubClientImpl) UnsetWebhook() error {
ctx := context.Background()
func (c *GithubClientImpl) UnsetWebhook(ctx *context.Context) error {

for _, hook := range c.hooks {
if c.cfg.GitProviderConfig.OrgLevelWebhook {

resp, err := c.client.Organizations.DeleteHook(ctx, c.cfg.GitProviderConfig.OrgName, *hook.ID)
resp, err := c.client.Organizations.DeleteHook(*ctx, c.cfg.GitProviderConfig.OrgName, *hook.ID)

if err != nil {
return err
Expand All @@ -196,7 +196,7 @@ func (c *GithubClientImpl) UnsetWebhook() error {

} else {
for _, repo := range strings.Split(c.cfg.GitProviderConfig.RepoList, ",") {
resp, err := c.client.Repositories.DeleteHook(ctx, c.cfg.GitProviderConfig.OrgName, repo, *hook.ID)
resp, err := c.client.Repositories.DeleteHook(*ctx, c.cfg.GitProviderConfig.OrgName, repo, *hook.ID)

if err != nil {
return fmt.Errorf("failed to delete repo level webhhok for %s, API call returned %d. %s", repo, resp.StatusCode, err)
Expand All @@ -207,6 +207,7 @@ func (c *GithubClientImpl) UnsetWebhook() error {
}
}
}
log.Printf("removed hook:%s\n", hook.GetURL()) // INFO
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/git_provider/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ type Client interface {
GetFile(ctx *context.Context, repo string, branch string, path string) (*CommitFile, error)
GetFiles(ctx *context.Context, repo string, branch string, paths []string) ([]*CommitFile, error)
SetWebhook() error
UnsetWebhook() error
UnsetWebhook(ctx *context.Context) error
HandlePayload(request *http.Request, secret []byte) (*WebhookPayload, error)
}
58 changes: 56 additions & 2 deletions pkg/server/server.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package server

import (
"context"
"github.com/gin-gonic/gin"
"github.com/rookout/piper/pkg/clients"
"github.com/rookout/piper/pkg/conf"
"github.com/rookout/piper/pkg/server/routes"
"log"
"net/http"
"os/signal"
"syscall"
"time"
)

func Init() *gin.Engine {
Expand All @@ -20,17 +25,66 @@ func Init() *gin.Engine {
}

func Start(cfg *conf.GlobalConfig, clients *clients.Clients) {
// Create context that listens for the interrupt signal from the OS.
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()

router := Init()

getRoutes(cfg, clients, router)

err := router.Run()
srv := &http.Server{
Addr: ":8080",
Handler: router,
}

// Initializing the server in a goroutine so that
// it won't block the graceful shutdown handling below
go func() {
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}()

err := clients.GitProvider.SetWebhook()
if err != nil {
panic(err)
}

// Listen for the interrupt signal.
<-ctx.Done()

// Restore default behavior on the interrupt signal and notify user of shutdown.
stop()
log.Println("shutting down gracefully...")

// The context is used to inform the server it has 10 seconds to finish
// the request it is currently handling
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

_ = gracefulShutdownHandler(&ctx, clients)

err = srv.Shutdown(ctx)
if err != nil {
log.Fatal(err)
log.Fatal("Server forced to shutdown: ", err)
}

log.Println("Server exiting")
}

func getRoutes(cfg *conf.GlobalConfig, clients *clients.Clients, router *gin.Engine) {
v1 := router.Group("/")
routes.AddHealthRoutes(cfg, v1)
routes.AddWebhookRoutes(cfg, clients, v1)
}

func gracefulShutdownHandler(ctx *context.Context, clients *clients.Clients) error {
err := clients.GitProvider.UnsetWebhook(ctx)
if err != nil {
log.Println("Unset webhook error: ", err) // ERROR
return err
}

return nil
}
2 changes: 1 addition & 1 deletion pkg/webhook_handler/webhook_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ func (m *MockGitProvider) SetWebhook() error {
return nil
}

func (m *MockGitProvider) UnsetWebhook() error {
func (m *MockGitProvider) UnsetWebhook(ctx *context.Context) error {
return nil
}

Expand Down

0 comments on commit dcd514c

Please sign in to comment.