Get outbound IP in multiple ways or disable cache server if failed to init (#74)
Fix #64 (incompletely). It's still not ideal. It makes more sense to use the gateway IP address of container network as outbound IP of cache server. However, this requires act to cooperate, some think like: - act creates the network for new container, and returns the network to runner. - runner extracts the gateway IP in the network. - runner uses the gateway IP as outbound IP, and pass it to act as cache server endpoint. - act It continues to create the container with the created network. Reviewed-on: https://gitea.com/gitea/act_runner/pulls/74 Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
parent
3463f94119
commit
3d78433564
4 changed files with 48 additions and 11 deletions
|
@ -18,7 +18,6 @@ import (
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-chi/chi/v5/middleware"
|
"github.com/go-chi/chi/v5/middleware"
|
||||||
"github.com/go-chi/render"
|
"github.com/go-chi/render"
|
||||||
"github.com/nektos/act/pkg/common"
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
"xorm.io/builder"
|
"xorm.io/builder"
|
||||||
|
@ -39,6 +38,8 @@ type Handler struct {
|
||||||
|
|
||||||
gc atomic.Bool
|
gc atomic.Bool
|
||||||
gcAt time.Time
|
gcAt time.Time
|
||||||
|
|
||||||
|
outboundIP string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHandler() (*Handler, error) {
|
func NewHandler() (*Handler, error) {
|
||||||
|
@ -69,6 +70,12 @@ func NewHandler() (*Handler, error) {
|
||||||
}
|
}
|
||||||
h.storage = storage
|
h.storage = storage
|
||||||
|
|
||||||
|
if ip, err := getOutboundIP(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
h.outboundIP = ip.String()
|
||||||
|
}
|
||||||
|
|
||||||
router := chi.NewRouter()
|
router := chi.NewRouter()
|
||||||
router.Use(middleware.RequestLogger(&middleware.DefaultLogFormatter{Logger: logger}))
|
router.Use(middleware.RequestLogger(&middleware.DefaultLogFormatter{Logger: logger}))
|
||||||
router.Use(func(handler http.Handler) http.Handler {
|
router.Use(func(handler http.Handler) http.Handler {
|
||||||
|
@ -113,7 +120,7 @@ func NewHandler() (*Handler, error) {
|
||||||
func (h *Handler) ExternalURL() string {
|
func (h *Handler) ExternalURL() string {
|
||||||
// TODO: make the external url configurable if necessary
|
// TODO: make the external url configurable if necessary
|
||||||
return fmt.Sprintf("http://%s:%d",
|
return fmt.Sprintf("http://%s:%d",
|
||||||
common.GetOutboundIP().String(),
|
h.outboundIP,
|
||||||
h.listener.Addr().(*net.TCPAddr).Port)
|
h.listener.Addr().(*net.TCPAddr).Port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ package artifactcache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -44,6 +45,33 @@ func parseContentRange(s string) (int64, int64, error) {
|
||||||
return start, stop, nil
|
return start, stop, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getOutboundIP() (net.IP, error) {
|
||||||
|
// FIXME: It makes more sense to use the gateway IP address of container network
|
||||||
|
if conn, err := net.Dial("udp", "8.8.8.8:80"); err == nil {
|
||||||
|
defer conn.Close()
|
||||||
|
return conn.LocalAddr().(*net.UDPAddr).IP, nil
|
||||||
|
}
|
||||||
|
if ifaces, err := net.Interfaces(); err == nil {
|
||||||
|
for _, i := range ifaces {
|
||||||
|
if addrs, err := i.Addrs(); err == nil {
|
||||||
|
for _, addr := range addrs {
|
||||||
|
var ip net.IP
|
||||||
|
switch v := addr.(type) {
|
||||||
|
case *net.IPNet:
|
||||||
|
ip = v.IP
|
||||||
|
case *net.IPAddr:
|
||||||
|
ip = v.IP
|
||||||
|
}
|
||||||
|
if ip.IsGlobalUnicast() {
|
||||||
|
return ip, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("no outbound IP address found")
|
||||||
|
}
|
||||||
|
|
||||||
// engine is a wrapper of *xorm.Engine, with a lock.
|
// engine is a wrapper of *xorm.Engine, with a lock.
|
||||||
// To avoid racing of sqlite, we don't care performance here.
|
// To avoid racing of sqlite, we don't care performance here.
|
||||||
type engine struct {
|
type engine struct {
|
||||||
|
|
|
@ -49,12 +49,6 @@ func runDaemon(ctx context.Context, envFile string) func(cmd *cobra.Command, arg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handler, err := artifactcache.NewHandler()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Infof("cache handler listens on: %v", handler.ExternalURL())
|
|
||||||
|
|
||||||
var g errgroup.Group
|
var g errgroup.Group
|
||||||
|
|
||||||
cli := client.New(
|
cli := client.New(
|
||||||
|
@ -72,7 +66,13 @@ func runDaemon(ctx context.Context, envFile string) func(cmd *cobra.Command, arg
|
||||||
Environ: cfg.Runner.Environ,
|
Environ: cfg.Runner.Environ,
|
||||||
Labels: cfg.Runner.Labels,
|
Labels: cfg.Runner.Labels,
|
||||||
Version: version,
|
Version: version,
|
||||||
CacheHandler: handler,
|
}
|
||||||
|
|
||||||
|
if handler, err := artifactcache.NewHandler(); err != nil {
|
||||||
|
log.Errorf("cannot init cache server, it will be disabled: %v", err)
|
||||||
|
} else {
|
||||||
|
log.Infof("cache handler listens on: %v", handler.ExternalURL())
|
||||||
|
runner.CacheHandler = handler
|
||||||
}
|
}
|
||||||
|
|
||||||
poller := poller.New(
|
poller := poller.New(
|
||||||
|
|
|
@ -27,7 +27,9 @@ func (s *Runner) Run(ctx context.Context, task *runnerv1.Task) error {
|
||||||
for k, v := range s.Environ {
|
for k, v := range s.Environ {
|
||||||
env[k] = v
|
env[k] = v
|
||||||
}
|
}
|
||||||
|
if s.CacheHandler != nil {
|
||||||
env["ACTIONS_CACHE_URL"] = s.CacheHandler.ExternalURL() + "/"
|
env["ACTIONS_CACHE_URL"] = s.CacheHandler.ExternalURL() + "/"
|
||||||
|
}
|
||||||
return NewTask(s.ForgeInstance, task.Id, s.Client, env, s.platformPicker).Run(ctx, task, s.Machine, s.Version)
|
return NewTask(s.ForgeInstance, task.Id, s.Client, env, s.platformPicker).Run(ctx, task, s.Machine, s.Version)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue