refactor: move commands to cmd/
This commit is contained in:
216
cmd/distro.go
Normal file
216
cmd/distro.go
Normal file
@@ -0,0 +1,216 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"github.com/cavaliergopher/grab/v3"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/remeh/sizedwaitgroup"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"code.dumpstack.io/tools/out-of-tree/cache"
|
||||
"code.dumpstack.io/tools/out-of-tree/distro"
|
||||
"code.dumpstack.io/tools/out-of-tree/distro/debian"
|
||||
"code.dumpstack.io/tools/out-of-tree/distro/debian/snapshot"
|
||||
"code.dumpstack.io/tools/out-of-tree/fs"
|
||||
)
|
||||
|
||||
type DistroCmd struct {
|
||||
List DistroListCmd `cmd:"" help:"list available distros"`
|
||||
|
||||
Debian DebianCmd `cmd:"" hidden:""`
|
||||
}
|
||||
|
||||
type DebianCmd struct {
|
||||
Cache DebianCacheCmd `cmd:"" help:"populate cache"`
|
||||
Fetch DebianFetchCmd `cmd:"" help:"download deb packages"`
|
||||
|
||||
Limit int `help:"limit amount of kernels to fetch"`
|
||||
Regex string `help:"match deb pkg names by regex" default:".*"`
|
||||
}
|
||||
|
||||
type DebianCacheCmd struct {
|
||||
Path string `help:"path to cache"`
|
||||
Refetch int `help:"days before refetch versions without deb package" default:"7"`
|
||||
UpdateRelease bool `help:"update release data"`
|
||||
UpdateKbuild bool `help:"update kbuild package"`
|
||||
Dump bool `help:"dump cache"`
|
||||
}
|
||||
|
||||
func (cmd *DebianCacheCmd) Run(dcmd *DebianCmd) (err error) {
|
||||
if cmd.Path != "" {
|
||||
debian.CachePath = cmd.Path
|
||||
}
|
||||
debian.RefetchDays = cmd.Refetch
|
||||
|
||||
log.Info().Msg("Fetching kernels...")
|
||||
|
||||
if dcmd.Limit == 0 {
|
||||
dcmd.Limit = math.MaxInt32
|
||||
}
|
||||
|
||||
mode := debian.NoMode
|
||||
if cmd.UpdateRelease {
|
||||
mode |= debian.UpdateRelease
|
||||
}
|
||||
if cmd.UpdateKbuild {
|
||||
mode |= debian.UpdateKbuild
|
||||
}
|
||||
|
||||
kernels, err := debian.GetKernelsWithLimit(dcmd.Limit, mode)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("")
|
||||
return
|
||||
}
|
||||
|
||||
if cmd.Dump {
|
||||
re, err := regexp.Compile(dcmd.Regex)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("regex")
|
||||
}
|
||||
|
||||
for _, kernel := range kernels {
|
||||
if !re.MatchString(kernel.Image.Deb.Name) {
|
||||
continue
|
||||
}
|
||||
fmt.Println(spew.Sdump(kernel))
|
||||
}
|
||||
}
|
||||
|
||||
log.Info().Msg("Success")
|
||||
return
|
||||
}
|
||||
|
||||
type DebianFetchCmd struct {
|
||||
Path string `help:"path to download directory" type:"existingdir" default:"./"`
|
||||
IgnoreMirror bool `help:"ignore check if packages on the mirror"`
|
||||
|
||||
Max int `help:"do not download more than X" default:"100500"`
|
||||
|
||||
Threads int `help:"parallel download threads" default:"8"`
|
||||
|
||||
Timeout time.Duration `help:"timeout for each download" default:"1m"`
|
||||
|
||||
swg sizedwaitgroup.SizedWaitGroup
|
||||
hasResults bool
|
||||
}
|
||||
|
||||
func (cmd *DebianFetchCmd) fetch(pkg snapshot.Package) {
|
||||
flog := log.With().
|
||||
Str("pkg", pkg.Deb.Name).
|
||||
Logger()
|
||||
|
||||
defer cmd.swg.Done()
|
||||
|
||||
if !cmd.IgnoreMirror {
|
||||
flog.Debug().Msg("check mirror")
|
||||
found, _ := cache.PackageURL(distro.Debian, pkg.Deb.URL)
|
||||
if found {
|
||||
flog.Debug().Msg("found on the mirror")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
target := filepath.Join(cmd.Path, filepath.Base(pkg.Deb.URL))
|
||||
|
||||
if fs.PathExists(target) {
|
||||
flog.Debug().Msg("already exists")
|
||||
return
|
||||
}
|
||||
|
||||
tmp, err := os.MkdirTemp(cmd.Path, "tmp-")
|
||||
if err != nil {
|
||||
flog.Fatal().Err(err).Msg("mkdir")
|
||||
return
|
||||
}
|
||||
defer os.RemoveAll(tmp)
|
||||
|
||||
flog.Info().Msg("fetch")
|
||||
flog.Debug().Msg(pkg.Deb.URL)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), cmd.Timeout)
|
||||
defer cancel()
|
||||
|
||||
req, err := grab.NewRequest(tmp, pkg.Deb.URL)
|
||||
if err != nil {
|
||||
flog.Warn().Err(err).Msg("cannot create request")
|
||||
return
|
||||
}
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
resp := grab.DefaultClient.Do(req)
|
||||
if err := resp.Err(); err != nil {
|
||||
flog.Warn().Err(err).Msg("request cancelled")
|
||||
return
|
||||
}
|
||||
|
||||
err = os.Rename(resp.Filename, target)
|
||||
if err != nil {
|
||||
flog.Fatal().Err(err).Msg("mv")
|
||||
}
|
||||
|
||||
cmd.hasResults = true
|
||||
cmd.Max--
|
||||
}
|
||||
|
||||
func (cmd *DebianFetchCmd) Run(dcmd *DebianCmd) (err error) {
|
||||
re, err := regexp.Compile(dcmd.Regex)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("regex")
|
||||
}
|
||||
|
||||
log.Info().Msg("will not download packages that exist on the mirror")
|
||||
log.Info().Msg("use --ignore-mirror if you really need it")
|
||||
|
||||
if dcmd.Limit == 0 {
|
||||
dcmd.Limit = math.MaxInt32
|
||||
}
|
||||
|
||||
kernels, err := debian.GetKernelsWithLimit(dcmd.Limit, debian.NoMode)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("")
|
||||
return
|
||||
}
|
||||
|
||||
var packages []snapshot.Package
|
||||
for _, kernel := range kernels {
|
||||
for _, pkg := range kernel.Packages() {
|
||||
if !re.MatchString(pkg.Deb.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
packages = append(packages, pkg)
|
||||
}
|
||||
}
|
||||
|
||||
cmd.swg = sizedwaitgroup.New(cmd.Threads)
|
||||
for _, pkg := range packages {
|
||||
if cmd.Max <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
cmd.swg.Add()
|
||||
go cmd.fetch(pkg)
|
||||
}
|
||||
cmd.swg.Wait()
|
||||
|
||||
if !cmd.hasResults {
|
||||
log.Fatal().Msg("no packages found to download")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type DistroListCmd struct{}
|
||||
|
||||
func (cmd *DistroListCmd) Run() (err error) {
|
||||
for _, d := range distro.List() {
|
||||
fmt.Println(d.ID, d.Release)
|
||||
}
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user