-
Notifications
You must be signed in to change notification settings - Fork 139
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Fixed pod readiness check Detect also if pod did not exited prematurely. Signed-off-by: Matej Vašek <[email protected]> * Removed dependency on sh/tar from alpine image This commit removes depencency on sh and tar binaries by implementing the logic in our func-util binary. Signed-off-by: Matej Vašek <[email protected]> --------- Signed-off-by: Matej Vašek <[email protected]>
- Loading branch information
1 parent
23668cb
commit 4de3725
Showing
8 changed files
with
617 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package tar | ||
|
||
import ( | ||
"archive/tar" | ||
"errors" | ||
"fmt" | ||
"io" | ||
"io/fs" | ||
"os" | ||
"path" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
func Extract(input io.Reader, destDir string) error { | ||
var err error | ||
|
||
des, err := os.ReadDir(destDir) | ||
if err != nil { | ||
return fmt.Errorf("cannot read dest dir: %w", err) | ||
} | ||
for _, de := range des { | ||
err = os.RemoveAll(filepath.Join(destDir, de.Name())) | ||
if err != nil { | ||
return fmt.Errorf("cannot purge dest dir: %w", err) | ||
} | ||
} | ||
|
||
r := tar.NewReader(input) | ||
|
||
var first bool = true | ||
for { | ||
var hdr *tar.Header | ||
hdr, err = r.Next() | ||
if err != nil { | ||
if errors.Is(err, io.EOF) { | ||
if first { | ||
// mimic tar output on empty input | ||
return fmt.Errorf("does not look like a tar") | ||
} | ||
return nil | ||
} | ||
return err | ||
} | ||
first = false | ||
|
||
name := hdr.Name | ||
linkname := hdr.Linkname | ||
if strings.Contains(name, "..") { | ||
return fmt.Errorf("name contains '..': %s", name) | ||
} | ||
if path.IsAbs(linkname) { | ||
return fmt.Errorf("absolute symlink: %s->%s", name, linkname) | ||
} | ||
if strings.HasPrefix(path.Clean(path.Join(path.Dir(name), linkname)), "..") { | ||
return fmt.Errorf("link target escapes: %s->%s", name, linkname) | ||
} | ||
|
||
var destPath, rel string | ||
destPath = filepath.Join(destDir, filepath.FromSlash(name)) | ||
rel, err = filepath.Rel(destDir, destPath) | ||
if err != nil { | ||
return fmt.Errorf("cannot get relative path: %w", err) | ||
} | ||
if strings.HasPrefix(rel, "..") { | ||
return fmt.Errorf("name escapes") | ||
} | ||
|
||
// ensure parent | ||
err = os.MkdirAll(filepath.Dir(destPath), os.FileMode(hdr.Mode)&fs.ModePerm|0111) | ||
if err != nil { | ||
return fmt.Errorf("cannot ensure parent: %w", err) | ||
} | ||
|
||
switch { | ||
case hdr.Typeflag == tar.TypeReg: | ||
err = writeRegularFile(destPath, os.FileMode(hdr.Mode&0777), r) | ||
case hdr.Typeflag == tar.TypeDir: | ||
err = os.MkdirAll(destPath, os.FileMode(hdr.Mode)&fs.ModePerm) | ||
case hdr.Typeflag == tar.TypeSymlink: | ||
err = os.Symlink(linkname, destPath) | ||
default: | ||
_, _ = fmt.Printf("unsupported type flag: %d\n", hdr.Typeflag) | ||
} | ||
if err != nil { | ||
return fmt.Errorf("cannot create entry: %w", err) | ||
} | ||
} | ||
} | ||
|
||
func writeRegularFile(target string, perm os.FileMode, content io.Reader) error { | ||
f, err := os.OpenFile(target, os.O_CREATE|os.O_EXCL|os.O_WRONLY, perm) | ||
if err != nil { | ||
return err | ||
} | ||
defer func(f *os.File) { | ||
_ = f.Close() | ||
}(f) | ||
_, err = io.Copy(f, content) | ||
if err != nil { | ||
return err | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
package tar_test | ||
|
||
import ( | ||
"archive/tar" | ||
"bytes" | ||
"io" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
tarutil "knative.dev/func/pkg/tar" | ||
) | ||
|
||
const ( | ||
aTxt1 = "a.txt first revision" | ||
bTxt1 = "b.txt first revision" | ||
aTxt2 = "a.txt second revision" | ||
bTxt2 = "b.txt second revision" | ||
) | ||
|
||
func TestExtract(t *testing.T) { | ||
var err error | ||
d := t.TempDir() | ||
err = tarutil.Extract(tarballV1(t), d) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
bs, err := os.ReadFile(filepath.Join(d, "dir/a.txt")) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
s := string(bs) | ||
if s != aTxt1 { | ||
t.Errorf("unexpected data: %s", s) | ||
} | ||
bs, err = os.ReadFile(filepath.Join(d, "dir/b.txt")) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
s = string(bs) | ||
if s != bTxt1 { | ||
t.Errorf("unexpected data: %s", s) | ||
} | ||
|
||
err = tarutil.Extract(tarballV2(t), d) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
bs, err = os.ReadFile(filepath.Join(d, "dir/a.txt")) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
s = string(bs) | ||
if s != aTxt2 { | ||
t.Errorf("unexpected data: %s", s) | ||
} | ||
bs, err = os.ReadFile(filepath.Join(d, "dir/b.txt")) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
s = string(bs) | ||
if s != bTxt2 { | ||
t.Errorf("unexpected data: %s", s) | ||
} | ||
} | ||
|
||
func tarballV1(t *testing.T) io.Reader { | ||
t.Helper() | ||
|
||
var err error | ||
var buff bytes.Buffer | ||
|
||
w := tar.NewWriter(&buff) | ||
defer func(w *tar.Writer) { | ||
_ = w.Close() | ||
}(w) | ||
|
||
err = w.WriteHeader(&tar.Header{ | ||
Name: "dir/a.txt", | ||
Typeflag: tar.TypeReg, | ||
Mode: 0644, | ||
Size: int64(len(aTxt1)), | ||
}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
_, err = w.Write([]byte(aTxt1)) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
err = w.WriteHeader(&tar.Header{ | ||
Name: "dir/data1", | ||
Typeflag: tar.TypeReg, | ||
Mode: 0644, | ||
Size: int64(len(bTxt1)), | ||
}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
_, err = w.Write([]byte(bTxt1)) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
err = w.WriteHeader(&tar.Header{ | ||
Name: "dir/b.txt", | ||
Linkname: "data1", | ||
Typeflag: tar.TypeSymlink, | ||
}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
return &buff | ||
} | ||
|
||
func tarballV2(t *testing.T) io.Reader { | ||
t.Helper() | ||
|
||
var err error | ||
var buff bytes.Buffer | ||
|
||
w := tar.NewWriter(&buff) | ||
defer func(w *tar.Writer) { | ||
_ = w.Close() | ||
}(w) | ||
|
||
err = w.WriteHeader(&tar.Header{ | ||
Name: "dir/a.txt", | ||
Typeflag: tar.TypeReg, | ||
Mode: 0644, | ||
Size: int64(len(aTxt2)), | ||
}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
_, err = w.Write([]byte(aTxt2)) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
err = w.WriteHeader(&tar.Header{ | ||
Name: "dir/b.txt", | ||
Linkname: "data2", | ||
Typeflag: tar.TypeSymlink, | ||
}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
err = w.WriteHeader(&tar.Header{ | ||
Name: "dir/data2", | ||
Typeflag: tar.TypeReg, | ||
Mode: 0644, | ||
Size: int64(len(bTxt2)), | ||
}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
_, err = w.Write([]byte(bTxt2)) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
return &buff | ||
} |
Oops, something went wrong.