mirror of
https://code.forgejo.org/forgejo/runner.git
synced 2025-08-11 17:50:58 +00:00
integrate the new cache proxy with the server viceice set up
This commit is contained in:
parent
a6a1df7556
commit
95e754c06b
3 changed files with 58 additions and 52 deletions
|
@ -20,6 +20,7 @@ import (
|
||||||
"github.com/timshannon/bolthold"
|
"github.com/timshannon/bolthold"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
|
|
||||||
|
"github.com/nektos/act/pkg/cacheproxy"
|
||||||
"github.com/nektos/act/pkg/common"
|
"github.com/nektos/act/pkg/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -83,12 +84,12 @@ func StartHandler(dir, outboundIP string, port uint16, secret string, logger log
|
||||||
}
|
}
|
||||||
|
|
||||||
router := httprouter.New()
|
router := httprouter.New()
|
||||||
router.GET(cachePrefixPath+urlBase+"/cache", h.middleware(h.find))
|
router.GET(urlBase+"/cache", h.middleware(h.find))
|
||||||
router.POST(cachePrefixPath+urlBase+"/caches", h.middleware(h.reserve))
|
router.POST(urlBase+"/caches", h.middleware(h.reserve))
|
||||||
router.PATCH(cachePrefixPath+urlBase+"/caches/:id", h.middleware(h.upload))
|
router.PATCH(urlBase+"/caches/:id", h.middleware(h.upload))
|
||||||
router.POST(cachePrefixPath+urlBase+"/caches/:id", h.middleware(h.commit))
|
router.POST(urlBase+"/caches/:id", h.middleware(h.commit))
|
||||||
router.GET(cachePrefixPath+urlBase+"/artifacts/:id", h.middleware(h.get))
|
router.GET(urlBase+"/artifacts/:id", h.middleware(h.get))
|
||||||
router.POST(cachePrefixPath+urlBase+"/clean", h.middleware(h.clean))
|
router.POST(urlBase+"/clean", h.middleware(h.clean))
|
||||||
|
|
||||||
h.router = router
|
h.router = router
|
||||||
|
|
||||||
|
@ -159,7 +160,8 @@ func (h *Handler) openDB() (*bolthold.Store, error) {
|
||||||
|
|
||||||
// GET /_apis/artifactcache/cache
|
// GET /_apis/artifactcache/cache
|
||||||
func (h *Handler) find(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
func (h *Handler) find(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
||||||
repo, err := h.validateMac(params)
|
rundata := runDataFromHeaders(r)
|
||||||
|
repo, err := h.validateMac(rundata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.responseJSON(w, r, 500, err)
|
h.responseJSON(w, r, 500, err)
|
||||||
return
|
return
|
||||||
|
@ -206,7 +208,8 @@ func (h *Handler) find(w http.ResponseWriter, r *http.Request, params httprouter
|
||||||
|
|
||||||
// POST /_apis/artifactcache/caches
|
// POST /_apis/artifactcache/caches
|
||||||
func (h *Handler) reserve(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
func (h *Handler) reserve(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
||||||
repo, err := h.validateMac(params)
|
rundata := runDataFromHeaders(r)
|
||||||
|
repo, err := h.validateMac(rundata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.responseJSON(w, r, 500, err)
|
h.responseJSON(w, r, 500, err)
|
||||||
return
|
return
|
||||||
|
@ -243,7 +246,8 @@ func (h *Handler) reserve(w http.ResponseWriter, r *http.Request, params httprou
|
||||||
|
|
||||||
// PATCH /_apis/artifactcache/caches/:id
|
// PATCH /_apis/artifactcache/caches/:id
|
||||||
func (h *Handler) upload(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
func (h *Handler) upload(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
||||||
repo, err := h.validateMac(params)
|
rundata := runDataFromHeaders(r)
|
||||||
|
repo, err := h.validateMac(rundata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.responseJSON(w, r, 500, err)
|
h.responseJSON(w, r, 500, err)
|
||||||
return
|
return
|
||||||
|
@ -296,7 +300,8 @@ func (h *Handler) upload(w http.ResponseWriter, r *http.Request, params httprout
|
||||||
|
|
||||||
// POST /_apis/artifactcache/caches/:id
|
// POST /_apis/artifactcache/caches/:id
|
||||||
func (h *Handler) commit(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
func (h *Handler) commit(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
||||||
repo, err := h.validateMac(params)
|
rundata := runDataFromHeaders(r)
|
||||||
|
repo, err := h.validateMac(rundata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.responseJSON(w, r, 500, err)
|
h.responseJSON(w, r, 500, err)
|
||||||
return
|
return
|
||||||
|
@ -363,7 +368,8 @@ func (h *Handler) commit(w http.ResponseWriter, r *http.Request, params httprout
|
||||||
|
|
||||||
// GET /_apis/artifactcache/artifacts/:id
|
// GET /_apis/artifactcache/artifacts/:id
|
||||||
func (h *Handler) get(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
func (h *Handler) get(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
||||||
repo, err := h.validateMac(params)
|
rundata := runDataFromHeaders(r)
|
||||||
|
repo, err := h.validateMac(rundata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.responseJSON(w, r, 500, err)
|
h.responseJSON(w, r, 500, err)
|
||||||
return
|
return
|
||||||
|
@ -403,7 +409,8 @@ func (h *Handler) get(w http.ResponseWriter, r *http.Request, params httprouter.
|
||||||
|
|
||||||
// POST /_apis/artifactcache/clean
|
// POST /_apis/artifactcache/clean
|
||||||
func (h *Handler) clean(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
func (h *Handler) clean(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
||||||
_, err := h.validateMac(params)
|
rundata := runDataFromHeaders(r)
|
||||||
|
_, err := h.validateMac(rundata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.responseJSON(w, r, 500, err)
|
h.responseJSON(w, r, 500, err)
|
||||||
return
|
return
|
||||||
|
@ -621,3 +628,12 @@ func parseContentRange(s string) (uint64, uint64, error) {
|
||||||
}
|
}
|
||||||
return start, stop, nil
|
return start, stop, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runDataFromHeaders(r *http.Request) cacheproxy.RunData {
|
||||||
|
return cacheproxy.RunData{
|
||||||
|
RepositoryFullName: r.Header.Get("Forgejo-Cache-Repo"),
|
||||||
|
RunNumber: r.Header.Get("Forgejo-Cache-RunNumber"),
|
||||||
|
Timestamp: r.Header.Get("Forgejo-Cache-Timestamp"),
|
||||||
|
RepositoryMAC: r.Header.Get("Forgejo-Cache-MAC"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,36 +6,29 @@ package artifactcache
|
||||||
import (
|
import (
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"hash"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/nektos/act/pkg/cacheproxy"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrValidation = errors.New("validation error")
|
ErrValidation = errors.New("validation error")
|
||||||
cachePrefixPath = "/:org/:repo/:run/:ts/:mac"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *Handler) validateMac(params httprouter.Params) (string, error) {
|
func (h *Handler) validateMac(rundata cacheproxy.RunData) (string, error) {
|
||||||
ts := params.ByName("ts")
|
|
||||||
|
|
||||||
repo := params.ByName("org") + "/" + params.ByName("repo")
|
|
||||||
run := params.ByName("run")
|
|
||||||
messageMAC := params.ByName("mac")
|
|
||||||
|
|
||||||
// TODO: allow configurable max age
|
// TODO: allow configurable max age
|
||||||
if !validateAge(ts) {
|
if !validateAge(rundata.Timestamp) {
|
||||||
return "", ErrValidation
|
return "", ErrValidation
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedMAC := computeMac(h.secret, repo, run, ts).Sum(nil)
|
expectedMAC := computeMac(h.secret, rundata.RepositoryFullName, rundata.RunNumber, rundata.Timestamp)
|
||||||
if hmac.Equal([]byte(messageMAC), expectedMAC) {
|
if expectedMAC == rundata.RepositoryMAC {
|
||||||
return repo, nil
|
return rundata.RepositoryFullName, nil
|
||||||
}
|
}
|
||||||
return repo, ErrValidation
|
return rundata.RepositoryFullName, ErrValidation
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateAge(ts string) bool {
|
func validateAge(ts string) bool {
|
||||||
|
@ -49,15 +42,10 @@ func validateAge(ts string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func computeMac(key, repo, run, ts string) hash.Hash {
|
func computeMac(secret, repo, run, ts string) string {
|
||||||
mac := hmac.New(sha256.New, []byte(key))
|
mac := hmac.New(sha256.New, []byte(secret))
|
||||||
mac.Write([]byte(repo))
|
mac.Write([]byte(repo))
|
||||||
mac.Write([]byte(run))
|
mac.Write([]byte(run))
|
||||||
mac.Write([]byte(ts))
|
mac.Write([]byte(ts))
|
||||||
return mac
|
return hex.EncodeToString(mac.Sum(nil))
|
||||||
}
|
|
||||||
|
|
||||||
func ComputeMac(key, repo, run, ts string) string {
|
|
||||||
mac := computeMac(key, repo, run, ts)
|
|
||||||
return string(mac.Sum(nil))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,19 +45,19 @@ type Handler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RunData struct {
|
type RunData struct {
|
||||||
repositoryFullName string
|
RepositoryFullName string
|
||||||
runNumber string
|
RunNumber string
|
||||||
timestamp string
|
Timestamp string
|
||||||
repositoryMAC string
|
RepositoryMAC string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) CreateRunData(fullName string, runNumber string, timestamp string) RunData {
|
func (h *Handler) CreateRunData(fullName string, runNumber string, timestamp string) RunData {
|
||||||
mac := computeMac(h.cacheSecret, fullName, runNumber, timestamp)
|
mac := computeMac(h.cacheSecret, fullName, runNumber, timestamp)
|
||||||
return RunData{
|
return RunData{
|
||||||
repositoryFullName: fullName,
|
RepositoryFullName: fullName,
|
||||||
runNumber: runNumber,
|
RunNumber: runNumber,
|
||||||
timestamp: timestamp,
|
Timestamp: timestamp,
|
||||||
repositoryMAC: mac,
|
RepositoryMAC: mac,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,16 +126,14 @@ func proxyRequestHandler(proxy *httputil.ReverseProxy) func(http.ResponseWriter,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) newReverseProxy(targetHost string) (*httputil.ReverseProxy, error) {
|
func (h *Handler) newReverseProxy(targetHost string) (*httputil.ReverseProxy, error) {
|
||||||
url, err := url.Parse(targetHost)
|
targetURL, err := url.Parse(targetHost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy := &httputil.ReverseProxy{
|
proxy := &httputil.ReverseProxy{
|
||||||
Rewrite: func(r *httputil.ProxyRequest) {
|
Rewrite: func(r *httputil.ProxyRequest) {
|
||||||
r.SetURL(url)
|
re := regexp.MustCompile(`/(\w+)(/_apis/artifactcache/.+)`)
|
||||||
r.Out.Host = r.In.Host // if desired
|
|
||||||
re := regexp.MustCompile(`/(\w+)/_apis/artifactcache`)
|
|
||||||
matches := re.FindStringSubmatch(r.In.URL.Path)
|
matches := re.FindStringSubmatch(r.In.URL.Path)
|
||||||
id := matches[1]
|
id := matches[1]
|
||||||
data, ok := h.runs.Load(id)
|
data, ok := h.runs.Load(id)
|
||||||
|
@ -146,11 +144,15 @@ func (h *Handler) newReverseProxy(targetHost string) (*httputil.ReverseProxy, er
|
||||||
// ! it really shouldn't happen anyway so it's fine for now
|
// ! it really shouldn't happen anyway so it's fine for now
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
uri := matches[2]
|
||||||
|
|
||||||
r.Out.Header.Add("Forgejo-Cache-Repo", runData.repositoryFullName)
|
r.SetURL(targetURL)
|
||||||
r.Out.Header.Add("Forgejo-Cache-RunNumber", runData.runNumber)
|
r.Out.URL.Path = uri
|
||||||
r.Out.Header.Add("Forgejo-Cache-Timestamp", runData.timestamp)
|
|
||||||
r.Out.Header.Add("Forgejo-Cache-MAC", runData.repositoryMAC)
|
r.Out.Header.Add("Forgejo-Cache-Repo", runData.RepositoryFullName)
|
||||||
|
r.Out.Header.Add("Forgejo-Cache-RunNumber", runData.RunNumber)
|
||||||
|
r.Out.Header.Add("Forgejo-Cache-Timestamp", runData.Timestamp)
|
||||||
|
r.Out.Header.Add("Forgejo-Cache-MAC", runData.RepositoryMAC)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return proxy, nil
|
return proxy, nil
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue