Skip to content
This repository has been archived by the owner on Feb 11, 2025. It is now read-only.

archive: Add absolute path mode #141

Merged
merged 7 commits into from
Sep 15, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

- [#133](https://github.com/meltwater/drone-cache/pull/133) bacnkend/s3: Fixed Anonymous Credentials Error on public buckets.
- [#141](https://github.com/meltwater/drone-cache/pull/141) archive/tar, archive/gzip:
add absolute path mode: fix an issue #130 with drone where it fails to make extraction if the passed path is an absoulte path.

- [#133](https://github.com/meltwater/drone-cache/pull/133) bacnkend/s3: Fixed Anonymous Credentials Error on public buckets.
- Fixes [#132](https://github.com/meltwater/drone-cache/issues/132)
- [#138](https://github.com/meltwater/drone-cache/pull/138) backend/gcs: Fix GCS to pass credentials correctly when `GCS_ENDPOINT` is not set.
- [#135](https://github.com/meltwater/drone-cache/issues/135) backend/gcs: Fixed parsing of GCS JSON key.
Expand Down
100 changes: 88 additions & 12 deletions archive/gzip/gzip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"

"github.com/go-kit/kit/log"
Expand All @@ -19,12 +20,21 @@ var (
testRoot = "testdata"
testRootMounted = "testdata/mounted"
testRootExtracted = "testdata/extracted"
testAbsPattern = "testdata_absolute"
)

func TestCreate(t *testing.T) {
test.Ok(t, os.MkdirAll(testRootMounted, 0755))
test.Ok(t, os.MkdirAll(testRootExtracted, 0755))
t.Cleanup(func() { os.RemoveAll(testRoot) })

testAbs, err := ioutil.TempDir("", testAbsPattern)
test.Ok(t, err)
test.Equals(t, filepath.IsAbs(testAbs), true)

t.Cleanup(func() {
os.RemoveAll(testRoot)
os.RemoveAll(testAbs)
})

for _, tc := range []struct {
name string
Expand Down Expand Up @@ -53,7 +63,7 @@ func TestCreate(t *testing.T) {
{
name: "existing mount paths",
tgz: New(log.NewNopLogger(), testRootMounted, true, flate.DefaultCompression),
srcs: exampleFileTree(t, "gzip_create"),
srcs: exampleFileTree(t, "gzip_create", testRootMounted),
written: 43, // 3 x tmpfile in dir, 1 tmpfile
err: nil,
},
Expand All @@ -71,12 +81,30 @@ func TestCreate(t *testing.T) {
written: 43,
err: nil,
},
{
name: "absolute mount paths",
tgz: New(log.NewNopLogger(), testRootMounted, true, flate.DefaultCompression),
srcs: exampleFileTree(t, "tar_create", testAbs),
written: 43,
err: nil,
},
} {
tc := tc // NOTE: https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables
tc := tc // NOTICE: https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

// Setup
var absSrcs []string
var relativeSrcs []string

for _, src := range tc.srcs {
if strings.HasPrefix(src, "/") {
absSrcs = append(absSrcs, src)
} else {
relativeSrcs = append(relativeSrcs, src)
}
}

dstDir, dstDirClean := test.CreateTempDir(t, "gzip_create_archives", testRootMounted)
t.Cleanup(dstDirClean)

Expand All @@ -91,30 +119,46 @@ func TestCreate(t *testing.T) {
return
}

for _, src := range absSrcs {
test.Ok(t, os.RemoveAll(src))
}

test.Exists(t, archivePath)
test.Assert(t, written == tc.written, "case %q: written bytes got %d want %v", tc.name, written, tc.written)

_, err = extract(tc.tgz, archivePath, extDir)
test.Ok(t, err)
test.EqualDirs(t, extDir, testRootMounted, tc.srcs)
test.EqualDirs(t, extDir, testRootMounted, relativeSrcs)

for _, src := range absSrcs {
test.Exists(t, src)
}
})
}
}

func TestExtract(t *testing.T) {
test.Ok(t, os.MkdirAll(testRootMounted, 0755))
test.Ok(t, os.MkdirAll(testRootExtracted, 0755))
t.Cleanup(func() { os.RemoveAll(testRoot) })

testAbs, err := ioutil.TempDir("", testAbsPattern)
test.Ok(t, err)
test.Equals(t, filepath.IsAbs(testAbs), true)

t.Cleanup(func() {
os.RemoveAll(testRoot)
os.RemoveAll(testAbs)
})

// Setup
tgz := New(log.NewNopLogger(), testRootMounted, false, flate.DefaultCompression)

arcDir, arcDirClean := test.CreateTempDir(t, "gzip_extract_archive")
t.Cleanup(arcDirClean)

files := exampleFileTree(t, "gzip_extract")
files := exampleFileTree(t, "gzip_extract", testRootMounted)
archivePath := filepath.Join(arcDir, "test.tar.gz")
_, err := create(tgz, files, archivePath)
_, err = create(tgz, files, archivePath)
test.Ok(t, err)

nestedFiles := exampleNestedFileTree(t, "gzip_extract_nested")
Expand All @@ -134,6 +178,11 @@ func TestExtract(t *testing.T) {
badArchivePath := filepath.Join(arcDir, "bad_test.tar.gz")
test.Ok(t, ioutil.WriteFile(badArchivePath, []byte("hello\ndrone\n"), 0644))

filesAbs := exampleFileTree(t, ".gzip_extract_absolute", testAbs)
archiveAbsPath := filepath.Join(arcDir, "test_absolute.tar.gz")
_, err = create(tgz, filesAbs, archiveAbsPath)
test.Ok(t, err)

for _, tc := range []struct {
name string
tgz *Archive
Expand Down Expand Up @@ -198,22 +247,49 @@ func TestExtract(t *testing.T) {
written: 43,
err: nil,
},
{
name: "absolute mount paths",
tgz: New(log.NewNopLogger(), testRootMounted, true, flate.DefaultCompression),
archivePath: archiveAbsPath,
srcs: filesAbs,
written: 43,
err: nil,
},
} {
tc := tc // NOTE: https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables
t.Run(tc.name, func(t *testing.T) {
t.Parallel()

// Setup
var absSrcs []string
var relativeSrcs []string

for _, src := range tc.srcs {
if strings.HasPrefix(src, "/") {
absSrcs = append(absSrcs, src)
} else {
relativeSrcs = append(relativeSrcs, src)
}
}

dstDir, dstDirClean := test.CreateTempDir(t, "gzip_extract_"+tc.name, testRootExtracted)
t.Cleanup(dstDirClean)

// Run
for _, src := range absSrcs {
test.Ok(t, os.RemoveAll(src))
}
written, err := extract(tc.tgz, tc.archivePath, dstDir)
if err != nil {
test.Expected(t, err, tc.err)
return
}

// Test
test.Assert(t, written == tc.written, "case %q: written bytes got %d want %v", tc.name, written, tc.written)
test.EqualDirs(t, dstDir, testRootMounted, tc.srcs)
for _, src := range absSrcs {
test.Exists(t, src)
}
test.EqualDirs(t, dstDir, testRootMounted, relativeSrcs)
})
}
}
Expand Down Expand Up @@ -272,11 +348,11 @@ func extract(a *Archive, src string, dst string) (int64, error) {

// Fixtures

func exampleFileTree(t *testing.T, name string) []string {
file, fileClean := test.CreateTempFile(t, name, []byte("hello\ndrone!\n"), testRootMounted) // 13 bytes
func exampleFileTree(t *testing.T, name string, in string) []string {
file, fileClean := test.CreateTempFile(t, name, []byte("hello\ndrone!\n"), in) // 13 bytes
t.Cleanup(fileClean)

dir, dirClean := test.CreateTempFilesInDir(t, name, []byte("hello\ngo!\n"), testRootMounted) // 10 bytes
dir, dirClean := test.CreateTempFilesInDir(t, name, []byte("hello\ngo!\n"), in) // 10 bytes
t.Cleanup(dirClean)

return []string{file, dir}
Expand Down
11 changes: 9 additions & 2 deletions archive/tar/tar.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,14 @@ func writeToArchive(tw *tar.Writer, root string, skipSymlinks bool, written *int
}
}

name, err := relative(root, path)
var name string

if strings.HasPrefix(path, "/") {
name, err = filepath.Abs(path)
} else {
name, err = relative(root, path)
}

if err != nil {
return fmt.Errorf("relative name <%s>: <%s>, %w", path, root, err)
}
Expand Down Expand Up @@ -182,7 +189,7 @@ func (a *Archive) Extract(dst string, r io.Reader) (int64, error) {
}

var target string
if dst == h.Name {
if dst == h.Name || strings.HasPrefix(h.Name, "/") {
target = h.Name
} else {
name, err := relative(dst, h.Name)
Expand Down
Loading