Skip to content

Commit

Permalink
Add library function to strip out a single file from a deb package (#51)
Browse files Browse the repository at this point in the history
  • Loading branch information
griffin authored Jan 25, 2024
1 parent 49db64d commit 18cb69e
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 4 deletions.
2 changes: 2 additions & 0 deletions go.work.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034=
github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ=
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo=
1 change: 1 addition & 0 deletions go/pkg/deb2layer/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ go_test(
srcs = ["deb_test.go"],
embed = [":go_default_library"],
deps = ["@com_github_stretchr_testify//assert:go_default_library"],
data = ["testdeb.deb"],
)
52 changes: 51 additions & 1 deletion go/pkg/deb2layer/deb.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@ var (
// ErrDuplicateSection is returned when there is a duplicate deb package
// sections
ErrDuplicateSection = fmt.Errorf("duplicate section")

// ErrSectionNotFound is returned when an expected section is not found
ErrSectionNotFound = fmt.Errorf("section not found")
)

// DebToLayer convernts a deb package into a tarffile that can be used as a
// DebToLayer convernts a deb package into a tar file that can be used as a
// layer in an OCI image. Including adding the appropriate files for dpkg to
// track the package.
//
Expand Down Expand Up @@ -123,6 +126,53 @@ func DebToLayer(debReader io.Reader, writer io.Writer) error {
return nil
}

// CopyFileFromDeb copies a file from the debian file to a writer.
func CopyFileFromDeb(filename string, debReader io.Reader, writer io.Writer) error {
arReader := ar.NewReader(debReader)
for {
header, err := arReader.Next()
if err == io.EOF {
break
}
if err != nil {
return err
}

// > System V ar uses a '/' character (0x2F) to mark the end of the filename;
// https://en.wikipedia.org/wiki/Ar_(Unix)
name := header.Name
if strings.HasSuffix(name, "/") {
name = name[:len(name)-1]
}

if strings.HasPrefix(name, debDataFilePrefix) {
reader, err := extToReader(getFullExt(name), arReader)
if err != nil {
return err
}

tarReader, ok := reader.(*tar.Reader)
if !ok {
return fmt.Errorf("%q section is not a tar file: %q (%T)", debDataFilePrefix, name, reader)
}

_, err = seekToTarFile(tarReader, filename)
if err != nil {
return err
}

_, err = io.Copy(writer, tarReader)
if err != nil {
return err
}

return nil
}
}

return ErrSectionNotFound
}

// seekToTarFile seeks forward to the tar entry whose header's name is
// equivalent to the one provider. If found, the provided *tar.Reader will be
// left at the start of the data, otherwise it will leave at io.EOF.
Expand Down
23 changes: 20 additions & 3 deletions go/pkg/deb2layer/deb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ import (
"github.com/stretchr/testify/assert"
)

// Rebuild deb with `dpkg-deb -Zgzip --build testdeb`

var (
expectedFiles = []string{"/var/lib/dpkg/status.d/test", "./", "./deb_text.txt"}
expectedFiles = []string{"/var/lib/dpkg/status.d/testdeb", "./", "./deb_text.txt"}
)

// TestDebToLayer checks that the expected files are in the resulting layer
// based on a deb file created by Bazel's rules_pkg
func TestDebToLayer(t *testing.T) {
// XXX Fix generating deb package
t.Skip()
f, err := os.Open("test-tar-deb.deb")
f, err := os.Open("testdeb.deb")
if err != nil {
t.Fatalf("%v", err)
}
Expand Down Expand Up @@ -52,3 +53,19 @@ func TestDebToLayer(t *testing.T) {

assert.Equal(t, expectedFiles, actualFiles)
}

func TestCopyFileFromDeb(t *testing.T) {
f, err := os.Open("testdeb.deb")
if err != nil {
t.Fatalf("%v", err)
}
defer f.Close()

var buf bytes.Buffer
err = CopyFileFromDeb("deb_text.txt", f, &buf)
if err != nil {
t.Fatalf("%v", err)
}

assert.Equal(t, "my-deb\n", buf.String())
}
Binary file added go/pkg/deb2layer/testdeb.deb
Binary file not shown.
5 changes: 5 additions & 0 deletions go/pkg/deb2layer/testdeb/DEBIAN/control
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Package: testdeb
Version: 0.0.1
Maintainer: DataDog
Architecture: all
Description: hello world
File renamed without changes.

0 comments on commit 18cb69e

Please sign in to comment.