Skip to content

Commit

Permalink
fix: clear binaries dir before relink and make sure link paths are th…
Browse files Browse the repository at this point in the history
…e same (cashapp#393)

These changes fixes two bugs happen when hermit download and relink due
to manifest destination changes for a given package.

1. relink is skipped due to only checking the existance for the link.
   Instead, link destination should also be checked.

2. relink failed due to link exists previously.  => solved by remove the
   link directories prior to creation
  • Loading branch information
lyonlai authored Feb 5, 2024
1 parent 880e21c commit 23f33bc
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 0 deletions.
14 changes: 14 additions & 0 deletions state/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,11 @@ func (s *State) CacheAndDigest(b *ui.Task, p *manifest.Package) (string, error)

func (s *State) linkBinaries(p *manifest.Package) error {
dir := filepath.Join(s.binaryDir, p.Reference.String())
// clean up the binaryDir before
if err := os.RemoveAll(dir); err != nil {
return errors.WithStack(err)
}

if err := os.MkdirAll(dir, 0700); err != nil {
return errors.WithStack(err)
}
Expand Down Expand Up @@ -424,6 +429,15 @@ func (s *State) areBinariesLinked(p *manifest.Package) bool {
if _, err := os.Stat(linkPath); err != nil {
return false
}
// also checks the link destination matches the binary path.
ld, err := os.Readlink(linkPath)
if err != nil {
return false
}

if bin != ld {
return false
}
}
return true
}
Expand Down
38 changes: 38 additions & 0 deletions state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,41 @@ func TestCacheAndUnpackCreatesBinarySymlinks(t *testing.T) {
_, err = os.Stat(filepath.Join(state.BinaryDir(), pkg.Reference.String(), "linux_exe"))
assert.NoError(t, err)
}

func TestUpdateSymlinks(t *testing.T) {
fixture := NewStateTestFixture(t).
WithHTTPHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fr, err := os.Open("../archive/testdata/archive.tar.gz")
assert.NoError(t, err)
defer fr.Close() // nolint
_, err = io.Copy(w, fr)
assert.NoError(t, err)
}))
defer fixture.Clean()
state := fixture.State()
log, _ := ui.NewForTesting()
pkgDir := state.PkgDir()
pkg := manifesttest.NewPkgBuilder(pkgDir).
WithSource(fixture.Server.URL).
WithName("test").
Result()
assert.NoError(t, state.CacheAndUnpack(log.Task("test"), pkg))
newPkg := manifesttest.NewPkgBuilder(pkgDir + "-new").
WithSource(fixture.Server.URL).
WithName("test").
Result()

// unpack and make new links
assert.NoError(t, state.CacheAndUnpack(log.Task("test"), newPkg))

darwinExec := filepath.Join(state.BinaryDir(), newPkg.Reference.String(), "darwin_exe")
linuxExec := filepath.Join(state.BinaryDir(), newPkg.Reference.String(), "linux_exe")
darwinLink, err := os.Readlink(darwinExec)
assert.NoError(t, err)
assert.Equal(t, filepath.Join(newPkg.Dest, "darwin_exe"), darwinLink)

linuxLink, err := os.Readlink(linuxExec)
assert.NoError(t, err)
assert.Equal(t, filepath.Join(newPkg.Dest, "linux_exe"), linuxLink)

}

0 comments on commit 23f33bc

Please sign in to comment.