Skip to content

Commit

Permalink
feat(tiup-publisher): add notify when publish failed.
Browse files Browse the repository at this point in the history
Signed-off-by: wuhuizuo <wuhuizuo@126.com>
  • Loading branch information
wuhuizuo committed Oct 11, 2024
1 parent 0b8b9f9 commit 9c284f5
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 41 deletions.
88 changes: 69 additions & 19 deletions tiup-publisher/handler.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package main

import (
"bytes"
"context"
"crypto/sha256"
"encoding/json"
"fmt"
"io"
"net/http"
Expand All @@ -12,7 +14,7 @@ import (
"strings"

cloudevents "github.com/cloudevents/sdk-go/v2"
"github.com/rs/zerolog/log"
"github.com/rs/zerolog"
"oras.land/oras-go/v2/registry/remote"
"oras.land/oras-go/v2/registry/remote/auth"
"oras.land/oras-go/v2/registry/remote/retry"
Expand All @@ -21,11 +23,20 @@ import (
)

type Handler struct {
mirrorsURL string
mirrorURL string
larkWebhookURL string
logger zerolog.Logger
}

func NewHandler(mirror string) (*Handler, error) {
return &Handler{mirror}, nil
func NewHandler(mirrorURL, larkWebhookURL string, logger *zerolog.Logger) (*Handler, error) {
handler := Handler{mirrorURL: mirrorURL, larkWebhookURL: larkWebhookURL}
if logger == nil {
handler.logger = zerolog.New(os.Stderr).With().Timestamp().Logger()
} else {
handler.logger = *logger
}

return &handler, nil
}

func (h *Handler) SupportEventTypes() []string {
Expand All @@ -50,29 +61,68 @@ func (h *Handler) handleImpl(data *PublishRequestEvent) cloudevents.Result {
// 1. get the the tarball from data.From.
saveTo, err := downloadFile(data)
if err != nil {
log.Err(err).Msg("download file failed")
h.logger.Err(err).Msg("download file failed")
// h.notifyLark(&data.Publish, err)
return cloudevents.NewReceipt(true, "download file failed: %v", err)
}
log.Info().Msg("download file success")
h.logger.Info().Msg("download file success")

// 2. publish the tarball to the mirror.
if err := publish(saveTo, &data.Publish, h.mirrorsURL); err != nil {
log.Err(err).Msg("publish to mirror failed")
if err := h.publish(saveTo, &data.Publish); err != nil {
h.logger.Err(err).Msg("publish to mirror failed")
h.notifyLark(&data.Publish, err)
return cloudevents.NewReceipt(true, "publish to mirror failed: %v", err)
}
log.Info().Msg("publish to mirror success")
h.logger.Info().Msg("publish to mirror success")

// 3. check the package is in the mirror.
// printf 'post_check "$(tiup mirror show)/%s-%s-%s-%s.tar.gz" "%s"\n' \
remoteURL := fmt.Sprintf("%s/%s-%s-%s-%s.tar.gz", h.mirrorsURL, data.Publish.Name, data.Publish.Version, data.Publish.OS, data.Publish.Arch)
remoteURL := fmt.Sprintf("%s/%s-%s-%s-%s.tar.gz", h.mirrorURL, data.Publish.Name, data.Publish.Version, data.Publish.OS, data.Publish.Arch)
if err := postCheck(saveTo, remoteURL); err != nil {
log.Err(err).Str("remote", remoteURL).Msg("post check failed")
h.logger.Err(err).Str("remote", remoteURL).Msg("post check failed")
return cloudevents.NewReceipt(true, "post check failed: %v", err)
}
log.Info().Str("remote", remoteURL).Msg("post check success")

h.logger.Info().Str("remote", remoteURL).Msg("post check success")
return cloudevents.ResultACK
}

func (h *Handler) notifyLark(publishInfo *PublishInfo, err error) {
if h.larkWebhookURL == "" {
return
}

message := fmt.Sprintf("Failed to publish %s-%s @%s/%s platform to mirror %s: %v",
publishInfo.Name,
publishInfo.Version,
publishInfo.OS,
publishInfo.Arch,
h.mirrorURL,
err)

payload := map[string]interface{}{
"msg_type": "text",
"content": map[string]string{
"text": message,
},
}

jsonPayload, err := json.Marshal(payload)
if err != nil {
h.logger.Err(err).Msg("failed to marshal JSON payload")
}

resp, err := http.Post(h.larkWebhookURL, "application/json", bytes.NewBuffer(jsonPayload))
if err != nil {
h.logger.Err(err).Msg("failed to send notification to Lark")
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
h.logger.Error().Msgf("Lark API returned non-OK status: %d", resp.StatusCode)
}
}

func downloadFile(data *PublishRequestEvent) (string, error) {
switch data.From.Type {
case FromTypeOci:
Expand All @@ -81,26 +131,26 @@ func downloadFile(data *PublishRequestEvent) (string, error) {
case FromTypeHTTP:
return downloadHTTPFile(data.From.HTTP.URL)
default:
return "", nil
return "", fmt.Errorf("unknown from type: %v", data.From.Type)
}
}

func publish(file string, info *PublishInfo, to string) error {
func (h *Handler) publish(file string, info *PublishInfo) error {
args := []string{"mirror", "publish", info.Name, info.Version, file, info.EntryPoint, "--os", info.OS, "--arch", info.Arch, "--desc", info.Description}
if info.Standalone {
args = append(args, "--standalone")
}
command := exec.Command("tiup", args...)
command.Env = os.Environ()
command.Env = append(command.Env, "TIUP_MIRRORS="+to)
log.Debug().Any("args", command.Args).Any("env", command.Args).Msg("will execute tiup command")
command.Env = append(command.Env, "TIUP_MIRRORS="+h.mirrorURL)
h.logger.Debug().Any("args", command.Args).Any("env", command.Args).Msg("will execute tiup command")
output, err := command.Output()
if err != nil {
log.Err(err).Msg("failed to execute tiup command")
h.logger.Err(err).Msg("failed to execute tiup command")
return err
}
log.Info().
Str("mirror", to).
h.logger.Info().
Str("mirror", h.mirrorURL).
Str("output", string(output)).
Msg("tiup package publish success")

Expand Down
4 changes: 2 additions & 2 deletions tiup-publisher/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
const testMirrorURL = "http://tiup.pingcap.net:8988"

func TestHandler_Handle(t *testing.T) {
t.Skip("manual test case")
// t.Skip("manual test case")

t.Run("Valid event data", func(tt *testing.T) {
event := event.New()
Expand All @@ -37,7 +37,7 @@ func TestHandler_Handle(t *testing.T) {
},
})

h := &Handler{testMirrorURL}
h, _ := NewHandler(testMirrorURL, "https://open.feishu.cn/open-apis/bot/v2/hook/<replace_me>", nil)
result := h.Handle(event)
assert.True(tt, cloudevents.IsACK(result))
tt.Fail()
Expand Down
2 changes: 1 addition & 1 deletion tiup-publisher/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func main() {
if err := yaml.Unmarshal(configData, &config); err != nil {
log.Fatal().Err(err).Msg("Error parsing config file")
}
handler, err := NewHandler(config.MirrorUrl)
handler, err := NewHandler(config.MirrorUrl, config.LarkWebhookURL, &log.Logger)
if err != nil {
log.Fatal().Err(err).Msg("Error creating handler")
}
Expand Down
28 changes: 9 additions & 19 deletions tiup-publisher/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ const (
)

type Config struct {
Brokers []string `yaml:"brokers"`
Topic string `yaml:"topic"`
Brokers []string `yaml:"brokers" json:"brokers,omitempty"`
Topic string `yaml:"topic" json:"topic,omitempty"`
Credentials struct {
Type string `yaml:"type"`
Username string `yaml:"username"`
Password string `yaml:"password"`
} `yaml:"credentials"`
ConsumerGroup string `yaml:"consumerGroup"`
MirrorUrl string `yaml:"mirrorUrl"`
Type string `yaml:"type" json:"type,omitempty"`
Username string `yaml:"username" json:"username,omitempty"`
Password string `yaml:"password" json:"password,omitempty"`
} `yaml:"credentials" json:"credentials,omitempty"`
ConsumerGroup string `yaml:"consumer_group" json:"consumer_group,omitempty"`
MirrorUrl string `yaml:"mirror_url" json:"mirror_url,omitempty"`
LarkWebhookURL string `yaml:"lark_webhook_url" json:"lark_webhook_url,omitempty"`
}

type PublishRequestEvent struct {
Expand Down Expand Up @@ -48,14 +49,3 @@ type FromOci struct {
type FromHTTP struct {
URL string `json:"url,omitempty"`
}

// 2024-09-23T20:02:29.932583969+08:00 tiup mirror publish ctl v8.4.0-alpha-nightly ctl-v8.4.0-alpha-41-gedb43c053-darwin-amd64.tar.gz ctl --os darwin --arch amd64 --desc "TiDB controller suite"

type TiupMirror struct {
Name string `yaml:"name,omitempty" json:"name,omitempty"`
URL string `yaml:"url,omitempty" json:"url,omitempty"`
Auth struct {
Username string `yaml:"username,omitempty" json:"username,omitempty"`
Password string `yaml:"password,omitempty" json:"password,omitempty"`
} `yaml:"auth,omitempty" json:"auth,omitempty"`
}

0 comments on commit 9c284f5

Please sign in to comment.