layer.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package server
  2. import (
  3. "crypto/sha256"
  4. "fmt"
  5. "io"
  6. "os"
  7. )
  8. type Layer struct {
  9. MediaType string `json:"mediaType"`
  10. Digest string `json:"digest"`
  11. Size int64 `json:"size"`
  12. From string `json:"from,omitempty"`
  13. status string
  14. }
  15. func NewLayer(r io.Reader, mediatype string) (*Layer, error) {
  16. blobs, err := GetBlobsPath("")
  17. if err != nil {
  18. return nil, err
  19. }
  20. temp, err := os.CreateTemp(blobs, "sha256-")
  21. if err != nil {
  22. return nil, err
  23. }
  24. defer temp.Close()
  25. defer os.Remove(temp.Name())
  26. sha256sum := sha256.New()
  27. if
  28. n, err := io.Copy(io.MultiWriter(temp, sha256sum), r)
  29. if err != nil {
  30. return nil, err
  31. }
  32. if err := temp.Close(); err != nil {
  33. return nil, err
  34. }
  35. digest := fmt.Sprintf("sha256:%x", sha256sum.Sum(nil))
  36. blob, err := GetBlobsPath(digest)
  37. if err != nil {
  38. return nil, err
  39. }
  40. status := "using existing layer"
  41. if _, err := os.Stat(blob); err != nil {
  42. status = "creating new layer"
  43. if err := os.Rename(temp.Name(), blob); err != nil {
  44. return nil, err
  45. }
  46. }
  47. return &Layer{
  48. MediaType: mediatype,
  49. Digest: digest,
  50. Size: n,
  51. status: fmt.Sprintf("%s %s", status, digest),
  52. }, nil
  53. }
  54. func NewLayerFromLayer(digest, mediatype, from string) (*Layer, error) {
  55. blob, err := GetBlobsPath(digest)
  56. if err != nil {
  57. return nil, err
  58. }
  59. fi, err := os.Stat(blob)
  60. if err != nil {
  61. return nil, err
  62. }
  63. return &Layer{
  64. MediaType: mediatype,
  65. Digest: digest,
  66. Size: fi.Size(),
  67. From: from,
  68. status: fmt.Sprintf("using existing layer %s", digest),
  69. }, nil
  70. }
  71. func (l *Layer) Open() (io.ReadSeekCloser, error) {
  72. blob, err := GetBlobsPath(l.Digest)
  73. if err != nil {
  74. return nil, err
  75. }
  76. return os.Open(blob)
  77. }
  78. func (l *Layer) Remove() error {
  79. ms, err := Manifests()
  80. if err != nil {
  81. return err
  82. }
  83. for _, m := range ms {
  84. for _, layer := range append(m.Layers, m.Config) {
  85. if layer.Digest == l.Digest {
  86. // something is using this layer
  87. return nil
  88. }
  89. }
  90. }
  91. blob, err := GetBlobsPath(l.Digest)
  92. if err != nil {
  93. return err
  94. }
  95. return os.Remove(blob)
  96. }