chainid.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // Copyright 2016 The Linux Foundation
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Package identity provides implementations of subtle calculations pertaining
  15. // to image and layer identity. The primary item present here is the ChainID
  16. // calculation used in identifying the result of subsequent layer applications.
  17. //
  18. // Helpers are also provided here to ease transition to the
  19. // github.com/opencontainers/go-digest package, but that package may be used
  20. // directly.
  21. package identity
  22. import "github.com/opencontainers/go-digest"
  23. // ChainID takes a slice of digests and returns the ChainID corresponding to
  24. // the last entry. Typically, these are a list of layer DiffIDs, with the
  25. // result providing the ChainID identifying the result of sequential
  26. // application of the preceding layers.
  27. func ChainID(dgsts []digest.Digest) digest.Digest {
  28. chainIDs := make([]digest.Digest, len(dgsts))
  29. copy(chainIDs, dgsts)
  30. ChainIDs(chainIDs)
  31. if len(chainIDs) == 0 {
  32. return ""
  33. }
  34. return chainIDs[len(chainIDs)-1]
  35. }
  36. // ChainIDs calculates the recursively applied chain id for each identifier in
  37. // the slice. The result is written direcly back into the slice such that the
  38. // ChainID for each item will be in the respective position.
  39. //
  40. // By definition of ChainID, the zeroth element will always be the same before
  41. // and after the call.
  42. //
  43. // As an example, given the chain of ids `[A, B, C]`, the result `[A,
  44. // ChainID(A|B), ChainID(A|B|C)]` will be written back to the slice.
  45. //
  46. // The input is provided as a return value for convenience.
  47. //
  48. // Typically, these are a list of layer DiffIDs, with the
  49. // result providing the ChainID for each the result of each layer application
  50. // sequentially.
  51. func ChainIDs(dgsts []digest.Digest) []digest.Digest {
  52. if len(dgsts) < 2 {
  53. return dgsts
  54. }
  55. parent := digest.FromBytes([]byte(dgsts[0] + " " + dgsts[1]))
  56. next := dgsts[1:]
  57. next[0] = parent
  58. ChainIDs(next)
  59. return dgsts
  60. }