1
0
out-of-tree/distro/debian/snapshot/snapshot.go

178 lines
3.0 KiB
Go
Raw Normal View History

2023-05-11 12:03:18 +00:00
package snapshot
import (
"errors"
"fmt"
"net/url"
2023-05-11 12:03:18 +00:00
"regexp"
"strings"
2023-05-11 16:26:16 +00:00
"time"
"github.com/rs/zerolog/log"
"golang.org/x/time/rate"
2023-05-11 12:03:18 +00:00
"code.dumpstack.io/tools/out-of-tree/distro/debian/snapshot/mr"
)
const timeLayout = "20060102T150405Z"
const URL = "https://snapshot.debian.org"
2023-05-11 16:26:16 +00:00
var Limiter = rate.NewLimiter(rate.Every(time.Second), 1)
// Retries in case of 5xx errors
var Retries = 10
var HttpTimeout = time.Second * 5
2023-05-11 12:03:18 +00:00
func SourcePackageVersions(name string) (versions []string, err error) {
pkg, err := mr.GetPackage(name)
if err != nil {
return
}
for _, res := range pkg.Result {
versions = append(versions, res.Version)
}
return
}
type Package struct {
Name string
Source string
Version string
Arch string
Deb struct {
2023-05-11 12:03:18 +00:00
Name string
Hash string
URL string
2023-05-11 12:03:18 +00:00
}
2023-05-11 12:03:18 +00:00
Repo struct {
Snapshot string
Archive string
Component string
2023-05-11 12:03:18 +00:00
}
}
func NewPackage(name, srcname, version string, archs []string) (
p Package, err error) {
2023-05-11 12:03:18 +00:00
p.Name = name
p.Source = srcname
p.Version = version
p.Arch, p.Deb.Hash, err = p.getHash(archs)
2023-05-11 12:03:18 +00:00
if err != nil {
return
}
info, err := mr.GetInfo(p.Deb.Hash)
2023-05-11 12:03:18 +00:00
if err != nil {
return
}
p.Deb.Name = info.Result[0].Name
2023-05-11 12:03:18 +00:00
p.Repo.Archive = info.Result[0].ArchiveName
p.Repo.Snapshot = info.Result[0].FirstSeen
p.Deb.URL, err = url.JoinPath(URL, "archive", p.Repo.Archive,
p.Repo.Snapshot, info.Result[0].Path, p.Deb.Name)
if err != nil {
return
}
split := strings.Split(info.Result[0].Path, "/")
if split[1] != "pool" || len(split) < 3 {
err = fmt.Errorf("incorrect path: %s", info.Result[0].Path)
return
}
p.Repo.Component = split[2]
2023-05-11 12:03:18 +00:00
return
}
func (p Package) getHash(archs []string) (arch, hash string, err error) {
2023-05-11 12:03:18 +00:00
binfiles, err := mr.GetBinfiles(p.Name, p.Version)
if err != nil {
return
}
for _, res := range binfiles.Result {
for _, allowedArch := range archs {
if res.Architecture == allowedArch {
arch = res.Architecture
hash = res.Hash
return
}
2023-05-11 12:03:18 +00:00
}
}
2023-05-11 16:26:16 +00:00
err = errors.New("hash not found")
return
}
2023-05-11 21:20:00 +00:00
func contains(pkgs []Package, pkg Package) bool {
for _, p := range pkgs {
if p.Name == pkg.Name {
return true
}
}
return false
}
2023-05-11 22:17:31 +00:00
func filtered(s string, filter []string) bool {
for _, f := range filter {
if strings.Contains(s, f) {
return true
}
}
return false
}
func Packages(srcname, version, regex string, archs, filter []string) (
pkgs []Package, err error) {
2023-05-11 22:17:31 +00:00
2023-05-11 12:03:18 +00:00
binpkgs, err := mr.GetBinpackages(srcname, version)
2023-05-11 22:06:31 +00:00
if err == mr.ErrNotFound {
err = nil
return
}
2023-05-11 12:03:18 +00:00
if err != nil {
return
}
r := regexp.MustCompile(regex)
for _, res := range binpkgs.Result {
if res.Version != version {
continue
}
2023-05-11 22:17:31 +00:00
if !r.MatchString(res.Name) || filtered(res.Name, filter) {
2023-05-11 12:03:18 +00:00
continue
}
2023-05-11 20:24:54 +00:00
log.Trace().Msgf("matched %v", res.Name)
2023-05-11 12:03:18 +00:00
var pkg Package
pkg, err = NewPackage(res.Name, srcname, version, archs)
2023-05-11 12:03:18 +00:00
if err != nil {
return
}
2023-05-11 21:20:00 +00:00
if contains(pkgs, pkg) {
log.Trace().Msgf("%v already in slice O_o", pkg.Name)
continue
}
2023-05-11 20:24:54 +00:00
log.Trace().Msgf("append %v", pkg.Name)
2023-05-11 12:03:18 +00:00
pkgs = append(pkgs, pkg)
}
return
}