added multiple mirrors to round robin downloads from
This commit is contained in:
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
CacheRoot string `toml:"cache_root"`
|
CacheRoot string `toml:"cache_root"`
|
||||||
MirrorURL string `toml:"mirror_url"`
|
MirrorURLs []string `toml:"mirror_url"`
|
||||||
MirroredRepos []string `toml:"mirrored_repos"`
|
MirroredRepos []string `toml:"mirrored_repos"`
|
||||||
Port string `toml:"port"`
|
Port string `toml:"port"`
|
||||||
Auth AuthConfig `toml:"auth"`
|
Auth AuthConfig `toml:"auth"`
|
||||||
@@ -22,7 +22,7 @@ type AuthConfig struct {
|
|||||||
func NewConfig() *Config {
|
func NewConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
CacheRoot: "/home/ewpt3ch/dev/pacman-cache-server/tmprepo",
|
CacheRoot: "/home/ewpt3ch/dev/pacman-cache-server/tmprepo",
|
||||||
MirrorURL: "https://us.mirrors.cicku.me/archlinux/",
|
MirrorURLs: "https://us.mirrors.cicku.me/archlinux/",
|
||||||
Port: "8090",
|
Port: "8090",
|
||||||
Auth: AuthConfig{Token: "FakeToken"},
|
Auth: AuthConfig{Token: "FakeToken"},
|
||||||
}
|
}
|
||||||
@@ -48,8 +48,8 @@ func (c *Config) validate() error {
|
|||||||
if c.CacheRoot == "" {
|
if c.CacheRoot == "" {
|
||||||
return fmt.Errorf("cache root is required")
|
return fmt.Errorf("cache root is required")
|
||||||
}
|
}
|
||||||
if c.MirrorURL == "" {
|
if len(c.MirrorURLs) == 0 {
|
||||||
return fmt.Errorf("mirror url is required")
|
return fmt.Errorf("at least one mirror is required")
|
||||||
}
|
}
|
||||||
if c.Port == "" {
|
if c.Port == "" {
|
||||||
c.Port = "8090"
|
c.Port = "8090"
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
cache_root = "/home/ewpt3ch/dev/pacman-cache-server/tmprepo"
|
cache_root = "/home/ewpt3ch/dev/pacman-cache-server/tmprepo"
|
||||||
mirror_url = "https://us.mirrors.cicku.me/archlinux/"
|
mirror_url = ["https://us.mirrors.cicku.me/archlinux/",
|
||||||
|
"https://losangeles.mirror.pkgbuild.com/",
|
||||||
|
"https://mirror.givebytes.net/archlinux/"]
|
||||||
# array of upstream repos this server caches see pacman.conf
|
# array of upstream repos this server caches see pacman.conf
|
||||||
# or pacman docs for more info <core, extra, multilib>
|
# or pacman docs for more info <core, extra, multilib>
|
||||||
mirrored_repos = ["core", "extra"]
|
mirrored_repos = ["core", "extra"]
|
||||||
|
|||||||
Vendored
+16
-4
@@ -3,11 +3,13 @@ package cache
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/sync/singleflight"
|
"golang.org/x/sync/singleflight"
|
||||||
@@ -15,14 +17,15 @@ import (
|
|||||||
|
|
||||||
type Cache struct {
|
type Cache struct {
|
||||||
cacheRoot string
|
cacheRoot string
|
||||||
mirrorURL string
|
mirrorURLs []string
|
||||||
mirroredRepos []string
|
mirroredRepos []string
|
||||||
|
mirrorIdx atomic.Uint32
|
||||||
sf singleflight.Group //prevents duplicate downloads
|
sf singleflight.Group //prevents duplicate downloads
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
client http.Client
|
client http.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCache(cacheRoot string, mirrorURL string, mirroredRepos []string) *Cache {
|
func NewCache(cacheRoot string, mirrorURLs []string, mirroredRepos []string) *Cache {
|
||||||
transport := &http.Transport{
|
transport := &http.Transport{
|
||||||
DialContext: (&net.Dialer{
|
DialContext: (&net.Dialer{
|
||||||
Timeout: 5 * time.Second,
|
Timeout: 5 * time.Second,
|
||||||
@@ -32,7 +35,7 @@ func NewCache(cacheRoot string, mirrorURL string, mirroredRepos []string) *Cache
|
|||||||
|
|
||||||
return &Cache{
|
return &Cache{
|
||||||
cacheRoot: cacheRoot,
|
cacheRoot: cacheRoot,
|
||||||
mirrorURL: mirrorURL,
|
mirrorURLs: mirrorURLs,
|
||||||
mirroredRepos: mirroredRepos,
|
mirroredRepos: mirroredRepos,
|
||||||
client: http.Client{
|
client: http.Client{
|
||||||
Timeout: 15 * time.Second,
|
Timeout: 15 * time.Second,
|
||||||
@@ -42,7 +45,9 @@ func NewCache(cacheRoot string, mirrorURL string, mirroredRepos []string) *Cache
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Cache) Fetch(pkgPath string) error {
|
func (c *Cache) Fetch(pkgPath string) error {
|
||||||
|
log.Printf("pkgPath from Fetch %v", pkgPath)
|
||||||
_, err, _ := c.sf.Do(pkgPath, func() (any, error) {
|
_, err, _ := c.sf.Do(pkgPath, func() (any, error) {
|
||||||
|
log.Print("calling fetch")
|
||||||
return nil, c.fetch(pkgPath)
|
return nil, c.fetch(pkgPath)
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
@@ -62,7 +67,9 @@ func (c *Cache) fetch(pkgName string) error {
|
|||||||
tempPkgName := pkgName + ".tmp"
|
tempPkgName := pkgName + ".tmp"
|
||||||
tempPkgPath := filepath.Join(c.cacheRoot, tempPkgName) //full tmp write path
|
tempPkgPath := filepath.Join(c.cacheRoot, tempPkgName) //full tmp write path
|
||||||
outPkg := filepath.Join(c.cacheRoot, pkgName)
|
outPkg := filepath.Join(c.cacheRoot, pkgName)
|
||||||
pkgURL := c.mirrorURL + pkgName
|
pkgURL := c.nextMirror() + pkgName
|
||||||
|
|
||||||
|
log.Printf("fetching %v", pkgURL)
|
||||||
|
|
||||||
resp, err := c.client.Get(pkgURL)
|
resp, err := c.client.Get(pkgURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -92,3 +99,8 @@ func (c *Cache) fetch(pkgName string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Cache) nextMirror() string {
|
||||||
|
idx := c.mirrorIdx.Add(1) - 1
|
||||||
|
return c.mirrorURLs[idx%uint32(len(c.mirrorURLs))]
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ func main() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c := cache.NewCache(cfg.CacheRoot, cfg.MirrorURL, cfg.MirroredRepos)
|
c := cache.NewCache(cfg.CacheRoot, cfg.MirrorURLs, cfg.MirroredRepos)
|
||||||
srv := &Server{cfg: cfg, c: c}
|
srv := &Server{cfg: cfg, c: c}
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
|
|||||||
Reference in New Issue
Block a user