mirror of
https://gitea.com/gitea/runner.git
synced 2026-11-04 06:25:32 +00:00
Migrates the runner to `connectrpc.com/connect/v2` by pinning actionslib v1.5.0, which carries https://gitea.com/gitea/actionslib/pulls/28. The wire behaviour towards Gitea is unchanged and works against Gitea servers on connect v1 and v2. The client keeps v1's unlimited response size, and the error codes and messages the runner checks stay the same. Reviewed-on: https://gitea.com/gitea/runner/pulls/1325 Reviewed-by: bircni <[email protected]> Co-authored-by: silverwind <[email protected]>
103 lines
3.3 KiB
Go
103 lines
3.3 KiB
Go
// Copyright 2022 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package client
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"gitea.com/gitea/runner/internal/pkg/ver"
|
|
|
|
"connectrpc.com/connect/v2"
|
|
"connectrpc.com/connect/v2/connecthttp"
|
|
"gitea.dev/actionslib/ping/v1/pingv1connect"
|
|
"gitea.dev/actionslib/pkg/protocol"
|
|
"gitea.dev/actionslib/runner/v1/runnerv1connect"
|
|
)
|
|
|
|
func NewTransport(endpoint string, tlsConfig *tls.Config) *http.Transport {
|
|
transport := &http.Transport{
|
|
Proxy: http.ProxyFromEnvironment,
|
|
MaxIdleConns: 10,
|
|
MaxIdleConnsPerHost: 10, // All requests go to one host; default is 2 which causes frequent reconnects.
|
|
IdleConnTimeout: 90 * time.Second,
|
|
ForceAttemptHTTP2: true,
|
|
}
|
|
if strings.HasPrefix(endpoint, "https://") {
|
|
transport.TLSClientConfig = tlsConfig
|
|
}
|
|
return transport
|
|
}
|
|
|
|
func getHTTPClient(endpoint string, tlsConfig *tls.Config, timeout time.Duration, extraHeaders map[string]string) *http.Client {
|
|
return &http.Client{
|
|
Transport: NewTransport(endpoint, tlsConfig),
|
|
Timeout: timeout,
|
|
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
|
if len(via) >= 10 { // a custom CheckRedirect replaces net/http's own limit
|
|
return errors.New("stopped after 10 redirects")
|
|
}
|
|
from, to := via[0].URL, req.URL
|
|
if from.Hostname() != to.Hostname() || from.Scheme == "https" && to.Scheme != "https" {
|
|
for name, value := range extraHeaders {
|
|
if req.Header.Get(name) == value {
|
|
req.Header.Del(name)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
// New returns a new runner client. timeout bounds every RPC: without it a
|
|
// stalled connection parks the reporter for the whole job context, so logs and
|
|
// heartbeats stop together and the task is reaped as a zombie.
|
|
func New(endpoint string, tlsConfig *tls.Config, uuid, token string, timeout time.Duration, extraHeaders map[string]string, opts ...connecthttp.Option) *HTTPClient {
|
|
baseURL := strings.TrimRight(endpoint, "/") + "/api/actions"
|
|
|
|
opts = append([]connecthttp.Option{connecthttp.WithReadMaxBytes(0)}, opts...)
|
|
rpcClient := connect.NewClient(connecthttp.NewTransport(getHTTPClient(endpoint, tlsConfig, timeout, extraHeaders), baseURL, opts...), func(next connect.ClientFunc) connect.ClientFunc {
|
|
return func(ctx context.Context, spec connect.Spec) (connect.ClientStream, error) {
|
|
info, _ := connect.CallInfoForClientContext(ctx)
|
|
for name, value := range extraHeaders {
|
|
if info.RequestHeader().Get(name) == "" {
|
|
info.RequestHeader().Set(name, value)
|
|
}
|
|
}
|
|
info.RequestHeader().Set("User-Agent", "gitea-runner/"+ver.Version())
|
|
if uuid != "" {
|
|
info.RequestHeader().Set(protocol.UUIDHeader, uuid)
|
|
}
|
|
if token != "" {
|
|
info.RequestHeader().Set(protocol.TokenHeader, token)
|
|
}
|
|
return next(ctx, spec)
|
|
}
|
|
})
|
|
|
|
return &HTTPClient{
|
|
PingServiceClient: pingv1connect.NewPingServiceClient(rpcClient),
|
|
RunnerServiceClient: runnerv1connect.NewRunnerServiceClient(rpcClient),
|
|
endpoint: endpoint,
|
|
}
|
|
}
|
|
|
|
func (c *HTTPClient) Address() string {
|
|
return c.endpoint
|
|
}
|
|
|
|
var _ Client = (*HTTPClient)(nil)
|
|
|
|
// An HTTPClient manages communication with the runner API.
|
|
type HTTPClient struct {
|
|
pingv1connect.PingServiceClient
|
|
runnerv1connect.RunnerServiceClient
|
|
endpoint string
|
|
}
|