91 lines
2.7 KiB
Go
91 lines
2.7 KiB
Go
// Package mirror synchronizes remote package repositories into a local
|
|
// directory tree, preserving the upstream layout so the result can be
|
|
// served directly to package managers.
|
|
package mirror
|
|
|
|
import (
|
|
"net/url"
|
|
"path"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/grmrgecko/repo-sync/fetch"
|
|
)
|
|
|
|
// RepoType identifies the repository format being synchronized.
|
|
type RepoType string
|
|
|
|
const (
|
|
// RepoRPM synchronizes yum/dnf style repositories.
|
|
RepoRPM RepoType = "rpm"
|
|
// RepoDeb synchronizes apt style repositories.
|
|
RepoDeb RepoType = "deb"
|
|
// RepoArch synchronizes pacman style repositories.
|
|
RepoArch RepoType = "arch"
|
|
// RepoApk synchronizes Alpine apk style repositories.
|
|
RepoApk RepoType = "apk"
|
|
)
|
|
|
|
// Options configures a synchronization run.
|
|
type Options struct {
|
|
// Type selects the repository format.
|
|
Type RepoType
|
|
// URLs lists the repository or mirrorlist URLs to synchronize.
|
|
URLs []string
|
|
// Destination is the local directory repositories are placed under.
|
|
Destination string
|
|
// Trim drops this many leading URL path components when building the
|
|
// destination path.
|
|
Trim int
|
|
// Flat places repositories directly in Destination without copying the
|
|
// URL path.
|
|
Flat bool
|
|
// Discover crawls each URL's directory listings for repositories.
|
|
Discover bool
|
|
// DiscoverDepth limits how deep discovery crawls below each URL.
|
|
DiscoverDepth int
|
|
// Workers is the number of concurrent download workers.
|
|
Workers int
|
|
// Verify re-verifies checksums of existing local files.
|
|
Verify bool
|
|
// Prune deletes local files no longer part of the repository.
|
|
Prune bool
|
|
// PruneGrace defers pruning a file until it has been unreferenced for
|
|
// this long across runs.
|
|
PruneGrace time.Duration
|
|
// DryRun reports what would change without downloading packages or
|
|
// altering the published repository.
|
|
DryRun bool
|
|
// destBase, when set by the mirror server, pins the repository root
|
|
// directory directly instead of deriving it from the URL path.
|
|
destBase string
|
|
// Components limits deb synchronization to these components.
|
|
Components []string
|
|
// Architectures limits deb synchronization to these architectures.
|
|
Architectures []string
|
|
}
|
|
|
|
// repoDest maps a repository URL onto the destination directory according
|
|
// to the configured trimming rules.
|
|
func (o *Options) repoDest(repoURL string) (string, error) {
|
|
if o.destBase != "" {
|
|
return o.destBase, nil
|
|
}
|
|
if o.Flat {
|
|
return o.Destination, nil
|
|
}
|
|
u, err := url.Parse(repoURL)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
var segs []string
|
|
for _, seg := range strings.Split(u.Path, "/") {
|
|
if seg != "" {
|
|
segs = append(segs, seg)
|
|
}
|
|
}
|
|
if o.Trim >= len(segs) {
|
|
return o.Destination, nil
|
|
}
|
|
return fetch.LocalJoin(o.Destination, path.Join(segs[o.Trim:]...))
|
|
}
|