Skip to content
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

fix: Rename restart handler to reload #179

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,9 @@ func (c *Client) ScalePool(ctx context.Context, id string) (*Response, error) {
return c.do(req, nil)
}

// Restart restarts the Fireactions server.
func (c *Client) Restart(ctx context.Context) (*Response, error) {
req, err := c.newRequestWithContext(ctx, "POST", "/api/v1/restart", nil)
// Reload reloads the Fireactions server.
func (c *Client) Reload(ctx context.Context) (*Response, error) {
req, err := c.newRequestWithContext(ctx, "POST", "/api/v1/reload", nil)
if err != nil {
return nil, err
}
Expand Down
6 changes: 3 additions & 3 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import (
"github.com/stretchr/testify/assert"
)

func TestClient_Restart(t *testing.T) {
func TestClient_Reload(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" || r.URL.Path != "/api/v1/restart" {
if r.Method != "POST" || r.URL.Path != "/api/v1/reload" {
t.Errorf("unexpected request: %s %s", r.Method, r.URL.Path)
}

Expand All @@ -21,7 +21,7 @@ func TestClient_Restart(t *testing.T) {

client := NewClient(WithEndpoint(server.URL))

_, err := client.Restart(context.Background())
_, err := client.Reload(context.Background())

assert.NoError(t, err)
}
Expand Down
2 changes: 1 addition & 1 deletion commands/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func New() *cobra.Command {
return nil
})

cmd.AddCommand(newRestartCmd())
cmd.AddCommand(newReloadCmd())

cmd.AddGroup(&cobra.Group{ID: "main", Title: "Main application commands:"})
cmd.AddCommand(newServerCmd())
Expand Down
25 changes: 25 additions & 0 deletions commands/reload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package commands

import (
"github.com/spf13/cobra"
)

func newReloadCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "reload",
Short: "reload the server with the latest configuration (no downtime)",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error { return runReloadCmd(cmd, args) },
}

return cmd
}

func runReloadCmd(cmd *cobra.Command, _ []string) error {
_, err := client.Reload(cmd.Context())
if err != nil {
return err
}

return nil
}
File renamed without changes.
25 changes: 0 additions & 25 deletions commands/restart.go

This file was deleted.

14 changes: 14 additions & 0 deletions docs/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,17 @@ Curl example:
```bash
curl -X POST -H "X-API-Key: <API_KEY>" http://localhost:8080/api/v1/pools/my-pool/resume
```

### Reload the configuration

This endpoint reloads the configuration from disk.

```http
POST /api/v1/reload
```

Curl example:

```bash
curl -X POST -H "X-API-Key: <API_KEY>" http://localhost:8080/api/v1/reload
```
7 changes: 0 additions & 7 deletions docs/user-guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,6 @@ github:
#
# Default: 0
app_id: 12345
#
# The secret used to sign incoming webhooks. This is used to verify that the webhook is from GitHub.
# Not required, but recommended.
#
# Default: ""
#
webhook_secret: secret

#
# Pools configuration.
Expand Down
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ go 1.22.2
toolchain go1.22.4

require (
github.com/cbrgm/githubevents v1.16.1
github.com/containerd/errdefs v0.1.0
github.com/containerd/log v0.1.0
github.com/distribution/reference v0.6.0
Expand All @@ -15,7 +14,6 @@ require (
github.com/google/go-github/v63 v63.0.0
github.com/opencontainers/image-spec v1.1.0
github.com/rs/zerolog v1.33.0
github.com/samber/lo v1.47.0
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.9.0
go.uber.org/mock v0.4.0
Expand Down
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ github.com/bytedance/sonic v1.12.2/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKz
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM=
github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/cbrgm/githubevents v1.16.1 h1:SBocrNbOJFBx5iclYQuIrWJzLJ+LclCJ24ALz6yw6LY=
github.com/cbrgm/githubevents v1.16.1/go.mod h1:phgWWa6KOvvYdaxs6U9LOrgRB5Ha5NnuAIveu7FINdg=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
Expand Down Expand Up @@ -797,8 +795,6 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc=
github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
Expand Down
3 changes: 1 addition & 2 deletions server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ type MetricsConfig struct {
type GitHubConfig struct {
AppPrivateKey string `yaml:"app_private_key" validate:"required"`
AppID int64 `yaml:"app_id" validate:"required"`
WebhookSecret string `yaml:"webhook_secret" validate:""`
}

type RunnerConfig struct {
Expand Down Expand Up @@ -62,7 +61,7 @@ func DefaultConfig() *Config {
Metrics: &MetricsConfig{Enabled: true, Address: ":8081"},
BasicAuthEnabled: false,
BasicAuthUsers: map[string]string{},
GitHub: &GitHubConfig{AppPrivateKey: "", AppID: 0, WebhookSecret: ""},
GitHub: &GitHubConfig{AppPrivateKey: "", AppID: 0},
Pools: []*PoolConfig{},
LogLevel: "debug",
Debug: false,
Expand Down
42 changes: 3 additions & 39 deletions server/handlers.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
package server

import (
"context"
"net/http"

"github.com/cbrgm/githubevents/githubevents"
"github.com/gin-gonic/gin"
"github.com/google/go-github/v63/github"
"github.com/hostinger/fireactions"
"github.com/samber/lo"
)

func getHealthzHandler() gin.HandlerFunc {
Expand Down Expand Up @@ -98,46 +94,14 @@ func resumePoolHandler(p PoolManager) gin.HandlerFunc {
return f
}

func restartHandler(p PoolManager) gin.HandlerFunc {
func reloadHandler(p PoolManager) gin.HandlerFunc {
f := func(ctx *gin.Context) {
if err := p.Restart(ctx); err != nil {
if err := p.Reload(ctx); err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

ctx.JSON(http.StatusOK, gin.H{"message": "Pools restarted successfully"})
}

return f
}

func webhookGitHubHandler(p PoolManager, secret string) gin.HandlerFunc {
ge := githubevents.New(secret)
ge.OnWorkflowJobEventQueued(func(deliveryID, eventName string, event *github.WorkflowJobEvent) error {
pools, err := p.ListPools(context.Background())
if err != nil {
return err
}

for _, pool := range pools {
if !lo.Every(pool.config.Runner.Labels, event.WorkflowJob.Labels) {
continue
}

return pool.Scale(context.Background(), 1)
}

return nil
})

f := func(ctx *gin.Context) {
err := ge.HandleEventRequest(ctx.Request)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

ctx.Status(http.StatusOK)
ctx.JSON(http.StatusOK, gin.H{"message": "Pools reloaded successfully"})
}

return f
Expand Down
16 changes: 8 additions & 8 deletions server/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,18 +315,18 @@ func TestResumePoolHandler(t *testing.T) {
})
}

func TestRestartHandler(t *testing.T) {
func TestReloadHandler(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

t.Run("Success", func(t *testing.T) {
m := newMockPoolManager(mockCtrl)
m.EXPECT().Restart(gomock.Any()).Return(nil)
m.EXPECT().Reload(gomock.Any()).Return(nil)

router := gin.New()
router.POST("/api/v1/restart", restartHandler(m))
router.POST("/api/v1/reload", reloadHandler(m))

req, err := http.NewRequest("POST", "/api/v1/restart", nil)
req, err := http.NewRequest("POST", "/api/v1/reload", nil)
if err != nil {
t.Fatal(err)
}
Expand All @@ -339,20 +339,20 @@ func TestRestartHandler(t *testing.T) {
t.Errorf("Expected status code %d, but got %d", http.StatusOK, rec.Code)
}

expectedBody := `{"message":"Pools restarted successfully"}`
expectedBody := `{"message":"Pools reloaded successfully"}`
if rec.Body.String() != expectedBody {
t.Errorf("Expected response body %s, but got %s", expectedBody, rec.Body.String())
}
})

t.Run("Error", func(t *testing.T) {
m := newMockPoolManager(mockCtrl)
m.EXPECT().Restart(gomock.Any()).Return(errors.New("error"))
m.EXPECT().Reload(gomock.Any()).Return(errors.New("error"))

router := gin.New()
router.POST("/api/v1/restart", restartHandler(m))
router.POST("/api/v1/reload", reloadHandler(m))

req, err := http.NewRequest("POST", "/api/v1/restart", nil)
req, err := http.NewRequest("POST", "/api/v1/reload", nil)
if err != nil {
t.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion server/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ type PoolManager interface {
ScalePool(ctx context.Context, id string, delta int) error
PausePool(ctx context.Context, id string) error
ResumePool(ctx context.Context, id string) error
Restart(ctx context.Context) error
Reload(ctx context.Context) error
}
12 changes: 6 additions & 6 deletions server/interface_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,18 @@ func (mr *mockPoolManagerMockRecorder) PausePool(ctx, id any) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PausePool", reflect.TypeOf((*mockPoolManager)(nil).PausePool), ctx, id)
}

// Restart mocks base method.
func (m *mockPoolManager) Restart(ctx context.Context) error {
// Reload mocks base method.
func (m *mockPoolManager) Reload(ctx context.Context) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Restart", ctx)
ret := m.ctrl.Call(m, "Reload", ctx)
ret0, _ := ret[0].(error)
return ret0
}

// Restart indicates an expected call of Restart.
func (mr *mockPoolManagerMockRecorder) Restart(ctx any) *gomock.Call {
// Reload indicates an expected call of Reload.
func (mr *mockPoolManagerMockRecorder) Reload(ctx any) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Restart", reflect.TypeOf((*mockPoolManager)(nil).Restart), ctx)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Reload", reflect.TypeOf((*mockPoolManager)(nil).Reload), ctx)
}

// ResumePool mocks base method.
Expand Down
7 changes: 3 additions & 4 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ func New(config *Config, opts ...Opt) (*Server, error) {
s.metricsServer = metricsServer
}

handler.POST("/webhook/github", webhookGitHubHandler(s, config.GitHub.WebhookSecret))
handler.GET("/healthz", getHealthzHandler())
handler.GET("/version", getVersionHandler())

Expand All @@ -114,7 +113,7 @@ func New(config *Config, opts ...Opt) (*Server, error) {
v1.GET("/pools/:id", getPoolHandler(s))
v1.POST("/pools/:id/resume", resumePoolHandler(s))
v1.POST("/pools/:id/pause", pausePoolHandler(s))
v1.POST("/restart", restartHandler(s))
v1.POST("/reload", reloadHandler(s))
}

return s, nil
Expand Down Expand Up @@ -257,11 +256,11 @@ func (s *Server) ResumePool(ctx context.Context, id string) error {
return nil
}

func (s *Server) Restart(ctx context.Context) error {
func (s *Server) Reload(ctx context.Context) error {
s.l.Lock()
defer s.l.Unlock()

s.logger.Info().Msgf("Restarting server configuration")
s.logger.Info().Msgf("Reloading server configuration")
err := s.config.Load()
if err != nil {
return fmt.Errorf("loading config: %w", err)
Expand Down
1 change: 0 additions & 1 deletion server/testdata/config1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ github:
app_private_key: |
-----BEGIN RSA PRIVATE KEY-----
app_id: 12345
webhook_secret: secret

pools:
- name: fireactions-2vcpu-2gb
Expand Down
Loading