Skip to content

Commit

Permalink
Generate 16 byte length cache key for buildpack paths
Browse files Browse the repository at this point in the history
When generated key starts with zeros %x formatting strips first zeros.
Add padding to format up to 16 bytes to match the key generated by cloud
controller.
  • Loading branch information
mariash committed Jan 27, 2024
1 parent adea22d commit f4b2bc9
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 26 deletions.
22 changes: 12 additions & 10 deletions builder/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ var _ = Describe("Building", func() {
}

cpBuildpack := func(buildpack string) {
hash := fmt.Sprintf("%x", xxhash.Sum64String(buildpack))
cp(filepath.Join(buildpackFixtures, buildpack), filepath.Join(buildpacksDir, hash))
cp(filepath.Join(buildpackFixtures, buildpack), filepath.Join(buildpacksDir, buildpackHash(buildpack)))
}

BeforeEach(func() {
Expand Down Expand Up @@ -401,8 +400,7 @@ var _ = Describe("Building", func() {
Skip("warning is unnecessary on Windows")
}

hash := fmt.Sprintf("%x", xxhash.Sum64String("always-detects"))
binDetect := filepath.Join(buildpacksDir, hash, "bin", "detect")
binDetect := filepath.Join(buildpacksDir, buildpackHash("always-detects"), "bin", "detect")
Expect(os.Chmod(binDetect, 0644)).To(Succeed())
})

Expand Down Expand Up @@ -794,10 +792,10 @@ var _ = Describe("Building", func() {
})

It("the supply buildpacks caches supply output as $CACHE_DIR/<xxhash64 of buildpack URL>", func() {
supplyCacheDir := fmt.Sprintf("%x", xxhash.Sum64String("always-detects-creates-build-artifacts"))
supplyCacheDir := buildpackHash("always-detects-creates-build-artifacts")
Expect(files).To(ContainElement("./" + supplyCacheDir + "/supplied"))

supplyCacheDir = fmt.Sprintf("%x", xxhash.Sum64String("always-detects"))
supplyCacheDir = buildpackHash("always-detects")
Expect(files).To(ContainElement("./" + supplyCacheDir + "/supplied"))

content, err := exec.Command("tar", "-xzOf", outputBuildArtifactsCache, "./"+supplyCacheDir+"/supplied").Output()
Expand Down Expand Up @@ -835,10 +833,10 @@ var _ = Describe("Building", func() {
})

It("the supply buildpacks caches supply output as $CACHE_DIR/<xxhash64 of buildpack URL>", func() {
supplyCacheDir := fmt.Sprintf("%x", xxhash.Sum64String("always-detects-creates-build-artifacts"))
supplyCacheDir := buildpackHash("always-detects-creates-build-artifacts")
Expect(files).To(ContainElement("./" + supplyCacheDir + "/supplied"))

supplyCacheDir = fmt.Sprintf("%x", xxhash.Sum64String("always-detects"))
supplyCacheDir = buildpackHash("always-detects")
Expect(files).To(ContainElement("./" + supplyCacheDir + "/supplied"))

content, err := exec.Command("tar", "-xzOf", outputBuildArtifactsCache, "./"+supplyCacheDir+"/supplied").Output()
Expand All @@ -860,13 +858,13 @@ var _ = Describe("Building", func() {
BeforeEach(func() {
rand.Seed(time.Now().UnixNano())
cachedSupply = fmt.Sprintf("%d", rand.Int())
alwaysDetectsHash = fmt.Sprintf("%x", xxhash.Sum64String("always-detects"))
alwaysDetectsHash = buildpackHash("always-detects")
err := os.MkdirAll(filepath.Join(buildArtifactsCacheDir, alwaysDetectsHash), 0755)
Expect(err).To(BeNil())
err = ioutil.WriteFile(filepath.Join(buildArtifactsCacheDir, alwaysDetectsHash, "old-supply"), []byte(cachedSupply), 0644)
Expect(err).To(BeNil())

notInBuildpackOrderHash = fmt.Sprintf("%x", xxhash.Sum64String("not-in-buildpack-order"))
notInBuildpackOrderHash = buildpackHash("not-in-buildpack-order")
err = os.MkdirAll(filepath.Join(buildArtifactsCacheDir, notInBuildpackOrderHash), 0755)
Expect(err).To(BeNil())

Expand Down Expand Up @@ -1423,3 +1421,7 @@ func removeTrailingSpace(dirty []string) []string {

return clean
}

func buildpackHash(key string) string {
return fmt.Sprintf("%016x", xxhash.Sum64String(key))
}
2 changes: 1 addition & 1 deletion builder_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ func (s LifecycleBuilderConfig) BuildpackPath(buildpackName string) string {
if err == nil && buildpackURL.IsAbs() {
baseDir = s.BuildpacksDownloadDir()
}
return filepath.Join(baseDir, fmt.Sprintf("%x", xxhash.Sum64String(buildpackName)))
return filepath.Join(baseDir, fmt.Sprintf("%016x", xxhash.Sum64String(buildpackName)))
}

func (s LifecycleBuilderConfig) LegacyBuildpackPath(buildpackName string) string {
Expand Down
40 changes: 26 additions & 14 deletions builder_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,24 +96,36 @@ var _ = Describe("LifecycleBuilderConfig", func() {
})
})

It("returns the path to a given system buildpack using legacy md5", func() {
key := "my-buildpack/key/::"
Expect(builderConfig.LegacyBuildpackPath(key)).To(Equal(filepath.Join(pathPrefix(), "tmp", "buildpacks", "8b2f72a0702aed614f8b5d8f7f5b431b")))
})
Describe("LegacyBuildpackPath", func() {
It("returns the path to a given system buildpack using legacy md5", func() {
key := "my-buildpack/key/::"
Expect(builderConfig.LegacyBuildpackPath(key)).To(Equal(filepath.Join(pathPrefix(), "tmp", "buildpacks", "8b2f72a0702aed614f8b5d8f7f5b431b")))
})

It("returns the path to a given downloaded buildpack using legacy md5", func() {
key := "https://github.com/cloudfoundry/ruby-buildpack"
Expect(builderConfig.LegacyBuildpackPath(key)).To(Equal(filepath.Join(pathPrefix(), "tmp", "buildpackdownloads", "21de62d118ecb1f46d868d24f00839ef")))
It("returns the path to a given downloaded buildpack using legacy md5", func() {
key := "https://github.com/cloudfoundry/ruby-buildpack"
Expect(builderConfig.LegacyBuildpackPath(key)).To(Equal(filepath.Join(pathPrefix(), "tmp", "buildpackdownloads", "21de62d118ecb1f46d868d24f00839ef")))
})
})

It("returns the path to a given system buildpack", func() {
key := "my-buildpack/key/::"
Expect(builderConfig.BuildpackPath(key)).To(Equal(filepath.Join(pathPrefix(), "tmp", "buildpacks", "dc91f5556d3ae859")))
})
Describe("BuildpackPath", func() {
It("returns the path to a given system buildpack", func() {
key := "my-buildpack/key/::"
Expect(builderConfig.BuildpackPath(key)).To(Equal(filepath.Join(pathPrefix(), "tmp", "buildpacks", "dc91f5556d3ae859")))
})

It("returns the path to a given downloaded buildpack", func() {
key := "https://github.com/cloudfoundry/ruby-buildpack"
Expect(builderConfig.BuildpackPath(key)).To(Equal(filepath.Join(pathPrefix(), "tmp", "buildpackdownloads", "0e1df1251578f504")))
})

It("returns the path to a given downloaded buildpack", func() {
key := "https://github.com/cloudfoundry/ruby-buildpack"
Expect(builderConfig.BuildpackPath(key)).To(Equal(filepath.Join(pathPrefix(), "tmp", "buildpackdownloads", "e1df1251578f504")))
Context("when key generates hash that start with zeros", func() {
It("returns the path that contains 16 byte key hash", func() {
// xxhash starts with zeros
key := "a1b4aa82-e5ae-4736-8284-bdfb013a7121_2845c523cf4f4f1045b331982cc557ef761afde4dc9fc8777831563461309455"
Expect(builderConfig.BuildpackPath(key)).To(Equal(filepath.Join(pathPrefix(), "tmp", "buildpacks", "00c84a1da9e0c81e")))
})
})
})

It("returns the path to the staging metadata", func() {
Expand Down
2 changes: 1 addition & 1 deletion buildpackrunner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ func (runner *Runner) pathHasBinDirectory(pathToTest string) bool {
}

func (runner *Runner) supplyCachePath(buildpack string) string {
return filepath.Join(runner.config.BuildArtifactsCacheDir(), fmt.Sprintf("%x", xxhash.Sum64String(buildpack)))
return filepath.Join(runner.config.BuildArtifactsCacheDir(), fmt.Sprintf("%016x", xxhash.Sum64String(buildpack)))
}

func fileExists(file string) (bool, error) {
Expand Down

0 comments on commit f4b2bc9

Please sign in to comment.