Skip to content

Commit b75482b

Browse files
committed
When deploying via link, deploy symlinks directly instead of resolving them first.
1 parent f0c7784 commit b75482b

File tree

4 files changed

+17
-23
lines changed

4 files changed

+17
-23
lines changed

internal/smartlink/smartlink.go

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
)
1111

1212
// LinkContents will link the contents of src to desc
13-
func LinkContents(src, dest string, visited map[string]bool) error {
13+
func LinkContents(src, dest string) error {
1414
if !fileutils.DirExists(src) {
1515
return errs.New("src dir does not exist: %s", src)
1616
}
@@ -29,7 +29,7 @@ func LinkContents(src, dest string, visited map[string]bool) error {
2929
return errs.Wrap(err, "Reading dir %s failed", src)
3030
}
3131
for _, entry := range entries {
32-
if err := Link(filepath.Join(src, entry.Name()), filepath.Join(dest, entry.Name()), visited); err != nil {
32+
if err := Link(filepath.Join(src, entry.Name()), filepath.Join(dest, entry.Name())); err != nil {
3333
return errs.Wrap(err, "Link failed")
3434
}
3535
}
@@ -39,27 +39,21 @@ func LinkContents(src, dest string, visited map[string]bool) error {
3939

4040
// Link creates a link from src to target. MS decided to support Symlinks but only if you opt into developer mode (go figure),
4141
// which we cannot reasonably force on our users. So on Windows we will instead create dirs and hardlinks.
42-
func Link(src, dest string, visited map[string]bool) error {
43-
srcWasSymlink := isSymlink(src)
44-
42+
func Link(src, dest string) error {
4543
var err error
4644
src, dest, err = resolvePaths(src, dest)
4745
if err != nil {
4846
return errs.Wrap(err, "Could not resolve src and dest paths")
4947
}
5048

51-
if visited == nil {
52-
visited = make(map[string]bool)
53-
}
54-
if _, exists := visited[src]; exists && srcWasSymlink {
55-
// We've encountered a recursive link. This is most often the case when the resolved src has
56-
// already been visited. In that case, just link the dest to the src (which may be a directory;
57-
// this is fine).
58-
return linkFile(src, dest)
59-
}
60-
visited[src] = true
61-
6249
if fileutils.IsDir(src) {
50+
if isSymlink(src) {
51+
// Links to directories are okay on Linux and macOS, but will fail on Windows.
52+
// If we ever get here on Windows, the artifact being deployed is bad and there's nothing we
53+
// can do about it except receive the report from Rollbar and report it internally.
54+
return linkFile(src, dest)
55+
}
56+
6357
if err := fileutils.Mkdir(dest); err != nil {
6458
return errs.Wrap(err, "could not create directory %s", dest)
6559
}
@@ -68,7 +62,7 @@ func Link(src, dest string, visited map[string]bool) error {
6862
return errs.Wrap(err, "could not read directory %s", src)
6963
}
7064
for _, entry := range entries {
71-
if err := Link(filepath.Join(src, entry.Name()), filepath.Join(dest, entry.Name()), visited); err != nil {
65+
if err := Link(filepath.Join(src, entry.Name()), filepath.Join(dest, entry.Name())); err != nil {
7266
return errs.Wrap(err, "sub link failed")
7367
}
7468
}
@@ -153,11 +147,11 @@ func isSymlink(src string) bool {
153147
// This is to ensure that we're always comparing apples to apples when doing string comparisons on paths.
154148
func resolvePaths(src, dest string) (string, string, error) {
155149
var err error
156-
src, err = fileutils.ResolveUniquePath(src)
150+
src, err = filepath.Abs(filepath.Clean(src))
157151
if err != nil {
158152
return "", "", errs.Wrap(err, "Could not resolve src path")
159153
}
160-
dest, err = fileutils.ResolveUniquePath(dest)
154+
dest, err = filepath.Abs(filepath.Clean(dest))
161155
if err != nil {
162156
return "", "", errs.Wrap(err, "Could not resolve dest path")
163157
}

internal/smartlink/smartlink_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func TestLinkContentsWithCircularLink(t *testing.T) {
4242
err = os.Symlink(subDir, circularLink)
4343
require.NoError(t, err)
4444

45-
err = LinkContents(srcDir, destDir, nil)
45+
err = LinkContents(srcDir, destDir)
4646
if runtime.GOOS == "windows" {
4747
require.Error(t, err)
4848
return // hard links to directories are not allowed on Windows

pkg/runtime/depot.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func (d *depot) DeployViaLink(id strfmt.UUID, relativeSrc, absoluteDest string)
177177
}
178178

179179
// Copy or link the artifact files, depending on whether the artifact in question relies on file transformations
180-
if err := smartlink.LinkContents(absoluteSrc, absoluteDest, nil); err != nil {
180+
if err := smartlink.LinkContents(absoluteSrc, absoluteDest); err != nil {
181181
return errs.Wrap(err, "failed to link artifact")
182182
}
183183

@@ -295,7 +295,7 @@ func (d *depot) Undeploy(id strfmt.UUID, relativeSrc, path string) error {
295295
for sharedFile, relinkSrc := range redeploys {
296296
switch deploy.Type {
297297
case deploymentTypeLink:
298-
if err := smartlink.Link(relinkSrc, sharedFile, nil); err != nil {
298+
if err := smartlink.Link(relinkSrc, sharedFile); err != nil {
299299
return errs.Wrap(err, "failed to relink file")
300300
}
301301
case deploymentTypeCopy:

pkg/runtime/links_windows.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func supportsHardLinks(path string) (supported bool) {
4343
}
4444

4545
logging.Debug("Attempting to link '%s' to '%s'", lnk, target)
46-
err = smartlink.Link(target, lnk, nil)
46+
err = smartlink.Link(target, lnk)
4747
if err != nil {
4848
logging.Debug("Test link creation failed: %v", err)
4949
return false

0 commit comments

Comments
 (0)