Skip to content
Open
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
126 changes: 1 addition & 125 deletions api/build/auto_cancel.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,8 @@
package build

import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
"time"

"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
Expand All @@ -18,7 +13,6 @@ import (
"github.com/go-vela/server/compiler/types/pipeline"
"github.com/go-vela/server/constants"
"github.com/go-vela/server/database"
"github.com/go-vela/server/internal/token"
)

// AutoCancel is a helper function that checks to see if any pending or running
Expand Down Expand Up @@ -68,7 +62,7 @@ func AutoCancel(c *gin.Context, b *types.Build, rB *types.Build, cancelOpts *pip
}
case strings.EqualFold(status, constants.StatusRunning) && cancelOpts.Running:
// call cancelRunning routine for builds already running on worker
err := cancelRunning(c, rB)
_, err := CancelRunning(c, rB)
if err != nil {
return false, err
}
Expand All @@ -94,124 +88,6 @@ func AutoCancel(c *gin.Context, b *types.Build, rB *types.Build, cancelOpts *pip
return false, nil
}

// cancelRunning is a helper function that determines the executor currently running a build and sends an API call
// to that executor's worker to cancel the build.
func cancelRunning(c *gin.Context, b *types.Build) error {
l := c.MustGet("logger").(*logrus.Entry)

e := new([]types.Executor)
// retrieve the worker
w, err := database.FromContext(c).GetWorkerForHostname(c, b.GetHost())
if err != nil {
return err
}

// prepare the request to the worker to retrieve executors
client := http.DefaultClient
client.Timeout = 30 * time.Second
endpoint := fmt.Sprintf("%s/api/v1/executors", w.GetAddress())

req, err := http.NewRequestWithContext(context.Background(), "GET", endpoint, nil)
if err != nil {
return err
}

tm := c.MustGet("token-manager").(*token.Manager)

// set mint token options
mto := &token.MintTokenOpts{
Hostname: "vela-server",
TokenType: constants.WorkerAuthTokenType,
TokenDuration: time.Minute * 1,
}

// mint token
tkn, err := tm.MintToken(mto)
if err != nil {
return err
}

// add the token to authenticate to the worker
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tkn))

// make the request to the worker and check the response
resp, err := client.Do(req)
if err != nil {
return err
}

defer resp.Body.Close()

// Read Response Body
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return err
}

// parse response and validate at least one item was returned
err = json.Unmarshal(respBody, e)
if err != nil {
return err
}

for _, executor := range *e {
// check each executor on the worker running the build to see if it's running the build we want to cancel
if executor.Build.GetID() == b.GetID() {
// prepare the request to the worker
client := http.DefaultClient
client.Timeout = 30 * time.Second

// set the API endpoint path we send the request to
u := fmt.Sprintf("%s/api/v1/executors/%d/build/cancel", w.GetAddress(), executor.GetID())

req, err := http.NewRequestWithContext(context.Background(), "DELETE", u, nil)
if err != nil {
return err
}

tm := c.MustGet("token-manager").(*token.Manager)

// set mint token options
mto := &token.MintTokenOpts{
Hostname: "vela-server",
TokenType: constants.WorkerAuthTokenType,
TokenDuration: time.Minute * 1,
}

// mint token
tkn, err := tm.MintToken(mto)
if err != nil {
return err
}

// add the token to authenticate to the worker
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", tkn))

// perform the request to the worker
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()

l.Debugf("sent cancel request to worker %s (executor %d) for build %d", w.GetHostname(), executor.GetID(), b.GetID())

// Read Response Body
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return err
}

err = json.Unmarshal(respBody, b)
if err != nil {
return err
}
}
}

return nil
}

// isCancelable is a helper function that determines whether a `target` build should be auto-canceled
// given a current build that intends to supersede it.
func isCancelable(target *types.Build, current *types.Build) bool {
Expand Down
Loading