Don't skip symlinks during local source upload#355
Don't skip symlinks during local source upload#355dollierp wants to merge 4 commits intoshipwright-io:mainfrom
Conversation
Signed-off-by: Denis Ollier <dollierp@redhat.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
IrvingMg
left a comment
There was a problem hiding this comment.
Thanks for the PR!
Overall, LGTM. I left a couple of comments. It would also be nice to have unit tests for at least basic cases, as the changes are related to the core functionality of the upload command.
pkg/shp/streamer/tar.go
Outdated
| // skipPath inspect each path and makes sure it skips files the tar helper can't handle. | ||
| func (t *Tar) skipPath(fpath string, stat fs.FileInfo) bool { | ||
| if !stat.Mode().IsRegular() { | ||
| if !stat.Mode().IsRegular() && !(stat.Mode()&fs.ModeSymlink != 0) { |
There was a problem hiding this comment.
| if !stat.Mode().IsRegular() && !(stat.Mode()&fs.ModeSymlink != 0) { | |
| if !stat.Mode().IsRegular() && stat.Mode()&fs.ModeSymlink == 0 { |
nit
| target, err := os.Readlink(fpath) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| header.Linkname = target |
There was a problem hiding this comment.
Should we add validation or a warning if the symlink points outside the source directory?
Signed-off-by: Denis Ollier <dollierp@redhat.com>
Signed-off-by: Denis Ollier <dollierp@redhat.com>
|
Hi @IrvingMg, Thanks for your review. I updated the PR with new changes trying to address your remarks. Regards, |
There was a problem hiding this comment.
Pull request overview
This PR fixes a bug where symlinks were being skipped during local source uploads. Previously, the tar helper would skip any file that wasn't a regular file (including symlinks, directories, and other special file types). The changes now allow symlinks to be included in the tar archive while still skipping unsupported file types.
Changes:
- Modified
skipPathfunction to exclude symlinks from being skipped (allowing them to be processed) - Added symlink handling in
writeFileToTarto read symlink targets, detect if they point outside the source directory, and properly set the tar header linkname - Added
isSymlinkTargetOutsideOfDirfunction to check if symlink targets escape the source directory and warn appropriately - Updated test to verify that symlinks are captured in the tar archive
- Fixed documentation from "buildrun" to "build" command references
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pkg/shp/streamer/tar.go | Modified skipPath condition to allow symlinks through filtering |
| pkg/shp/streamer/util.go | Added symlink handling logic with safety check for targets pointing outside source directory |
| pkg/shp/streamer/tar_test.go | Enhanced test to verify symlinks are included in tar output |
| pkg/shp/cmd/build/upload.go | Fixed documentation typo from "buildrun" to "build" |
| docs/shp_build_upload.md | Updated documentation examples to match corrected command |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Hi @dollierp, thanks for the changes. There’s one more Copilot comment, could you take a look? |
|
Hi @IrvingMg, I updated the PR to make Copilot happy. Let me know if something else is missing. Regards. |
IrvingMg
left a comment
There was a problem hiding this comment.
Thanks again for the changes. I left a couple more comments.
pkg/shp/streamer/util.go
Outdated
|
|
||
| if outside, _ := isSymlinkTargetOutsideOfDir(absSrc, absTarget); outside { | ||
| relPath, _ := filepath.Rel(src, fpath) | ||
| fmt.Fprintf(os.Stderr, "WARNING: symlink %q points outside the source directory %q (target: %q)\n", relPath, absSrc, target) |
There was a problem hiding this comment.
Could we send the error through ioStreams.ErrOut?
test/symlink/symlink_inside_tree
Outdated
| @@ -0,0 +1 @@ | |||
| ../../test No newline at end of file | |||
There was a problem hiding this comment.
Would it be possible to create and delete the symlink at runtime to avoid committing it?
Signed-off-by: Denis Ollier <dollierp@redhat.com>
|
Hi @IrvingMg, I tried to address your latest remarks and updated the PR. Regards, |
IrvingMg
left a comment
There was a problem hiding this comment.
Thanks for the update, looks good overall. Just a few final comments from my side.
| return nil | ||
| } | ||
|
|
||
| func isSymlinkTargetOutsideOfDir(dir, target string) (bool, error) { |
There was a problem hiding this comment.
nit: Is it possible to replace this with https://pkg.go.dev/path/filepath#IsLocal?
|
|
||
| stdErr := errOut.String() | ||
|
|
||
| t.Run("symlinks", func(_ *testing.T) { |
There was a problem hiding this comment.
Since *testing.T is unused, should we drop the t.Run wrapper?
| os.Symlink("../test", baseDir+"/test/symlink_inside_tree") | ||
| os.Symlink("../../foobar/test", baseDir+"/test/symlink_outside_tree") | ||
|
|
||
| defer os.Remove(baseDir + "/test/symlink_inside_tree") |
There was a problem hiding this comment.
Instead of deferring, I think we can use t.Cleanup.
| ioStreams, _, _, errOut := genericclioptions.NewTestIOStreams() | ||
|
|
||
| baseDir := "../../.." | ||
| os.Symlink("../test", baseDir+"/test/symlink_inside_tree") |
There was a problem hiding this comment.
It might be a good idea to check the error here and fail in case of an error. For example:
if err := os.Symlink("../test", baseDir+"/test/symlink_inside_tree"); err != nil {
t.Fatalf("setup symlink: %v", err)
}
t.Cleanup(func() {
os.Remove(baseDir + "/test/symlink_inside_tree")
})
Changes
Don't skip symlinks during local source upload
/kind bug
Submitter Checklist
See the contributor guide
for details on coding conventions, github and prow interactions, and the code review process.
Release Notes