Skip to content

Commit

Permalink
added support for zstandard compressed debian data archives
Browse files Browse the repository at this point in the history
fixed an issue causing debian repositories to not fail when a package could not be found
added more test fixtures
  • Loading branch information
djcass44 committed Sep 30, 2023
1 parent caecdfc commit 11fc661
Show file tree
Hide file tree
Showing 8 changed files with 858 additions and 6 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/go-logr/logr v1.2.4
github.com/google/go-containerregistry v0.16.1
github.com/hashicorp/go-getter v1.7.2
github.com/klauspost/compress v1.17.0
github.com/knqyf263/go-deb-version v0.0.0-20230223133812-3ed183d23422
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.8.4
Expand Down Expand Up @@ -85,7 +86,6 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/levigross/grequests v0.0.0-20190908174114-253788527a1a // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
Expand Down
12 changes: 12 additions & 0 deletions pkg/archiveutil/tar.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"github.com/chainguard-dev/go-apk/pkg/fs"
"github.com/go-logr/logr"
"github.com/klauspost/compress/zstd"
"github.com/ulikunitz/xz"
"io"
"os"
Expand All @@ -24,6 +25,7 @@ func Guntar(ctx context.Context, r io.Reader, rootfs fs.FullFS) error {
return Untar(ctx, gzp, rootfs)
}

// XZuntar is the same as Untar, but it first decodes the XZ archive
func XZuntar(ctx context.Context, r io.Reader, rootfs fs.FullFS) error {
xzp, err := xz.NewReader(r)
if err != nil {
Expand All @@ -32,6 +34,16 @@ func XZuntar(ctx context.Context, r io.Reader, rootfs fs.FullFS) error {
return Untar(ctx, xzp, rootfs)
}

// Zuntar is the same as Untar, but it first decodes the Zstandard archive
func Zuntar(ctx context.Context, r io.Reader, rootfs fs.FullFS) error {
zp, err := zstd.NewReader(r)
if err != nil {
return err
}
defer zp.Close()
return Untar(ctx, zp, rootfs)
}

// Untar expands a tar archive into the given path.
func Untar(ctx context.Context, r io.Reader, rootfs fs.FullFS) error {
log := logr.FromContextOrDiscard(ctx)
Expand Down
1 change: 1 addition & 0 deletions pkg/debian/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func NewIndex(ctx context.Context, repository, release, component, arch string)
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode > 299 {
log.Info("failed to locate Packages.gz file", "url", target)
return nil, fmt.Errorf("http response failed with code: %d", resp.StatusCode)
}
log.V(1).Info("successfully downloaded index", "code", resp.StatusCode)
Expand Down
43 changes: 38 additions & 5 deletions pkg/packages/debian/debian.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package debian

import (
"context"
"errors"
"fmt"
"github.com/chainguard-dev/go-apk/pkg/fs"
v1 "github.com/djcass44/all-your-base/pkg/api/v1"
Expand Down Expand Up @@ -38,7 +39,7 @@ func NewPackageKeeper(ctx context.Context, repositories []string) (*PackageKeepe
}, nil
}

func (*PackageKeeper) Unpack(ctx context.Context, pkg string, rootfs fs.FullFS) error {
func (p *PackageKeeper) Unpack(ctx context.Context, pkg string, rootfs fs.FullFS) error {
log := logr.FromContextOrDiscard(ctx).WithValues("pkg", pkg)
log.Info("unpacking deb")

Expand All @@ -57,15 +58,44 @@ func (*PackageKeeper) Unpack(ctx context.Context, pkg string, rootfs fs.FullFS)
return err
}

// then we need to untar the 'data.tar.gz' file
// then we need to unpack the 'data.tar.X' file
// that contains the filesystem

dataF, err := tmpFs.Open("/data.tar.xz")
if _, err := tmpFs.Stat(dataXZ); err == nil {
return p.unpackXZ(ctx, tmpFs, rootfs)
}
if _, err := tmpFs.Stat(dataZstd); err == nil {
return p.unpackZstd(ctx, tmpFs, rootfs)
}

return errors.New("unknown or unsupported data archive")
}

const (
dataXZ = "/data.tar.xz"
dataZstd = "/data.tar.zst"
)

func (*PackageKeeper) unpackZstd(ctx context.Context, src fs.FullFS, dst fs.FullFS) error {
log := logr.FromContextOrDiscard(ctx)
log.V(1).Info("unpacking zstandard data archive")
f, err := src.Open(dataZstd)
if err != nil {
log.Error(err, "failed to open data.tar.gz file")
log.Error(err, "failed to open data.tar.xz file")
return err
}
return archiveutil.XZuntar(ctx, dataF, rootfs)
return archiveutil.Zuntar(ctx, f, dst)
}

func (*PackageKeeper) unpackXZ(ctx context.Context, src fs.FullFS, dst fs.FullFS) error {
log := logr.FromContextOrDiscard(ctx)
log.V(1).Info("unpacking xz data archive")
f, err := src.Open(dataXZ)
if err != nil {
log.Error(err, "failed to open data.tar.xz file")
return err
}
return archiveutil.XZuntar(ctx, f, dst)
}

func (p *PackageKeeper) Resolve(ctx context.Context, pkg string) ([]lockfile.Package, error) {
Expand All @@ -76,6 +106,9 @@ func (p *PackageKeeper) Resolve(ctx context.Context, pkg string) ([]lockfile.Pac
if err != nil {
return nil, err
}
if len(out) == 0 {
continue
}
names := make([]lockfile.Package, len(out))
for i := range out {
names[i] = lockfile.Package{
Expand Down
Loading

0 comments on commit 11fc661

Please sign in to comment.