layer.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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. n, err := io.Copy(io.MultiWriter(temp, sha256sum), r)
  28. if err != nil {
  29. return nil, err
  30. }
  31. if err := temp.Close(); err != nil {
  32. return nil, err
  33. }
  34. digest := fmt.Sprintf("sha256:%x", sha256sum.Sum(nil))
  35. blob, err := GetBlobsPath(digest)
  36. if err != nil {
  37. return nil, err
  38. }
  39. status := "using existing layer"
  40. if _, err := os.Stat(blob); err != nil {
  41. status = "creating new layer"
  42. if err := os.Rename(temp.Name(), blob); err != nil {
  43. return nil, err
  44. }
  45. }
  46. return &Layer{
  47. MediaType: mediatype,
  48. Digest: digest,
  49. Size: n,
  50. status: fmt.Sprintf("%s %s", status, digest),
  51. }, nil
  52. }
  53. func NewLayerFromLayer(digest, mediatype, from string) (*Layer, error) {
  54. blob, err := GetBlobsPath(digest)
  55. if err != nil {
  56. return nil, err
  57. }
  58. fi, err := os.Stat(blob)
  59. if err != nil {
  60. return nil, err
  61. }
  62. return &Layer{
  63. MediaType: mediatype,
  64. Digest: digest,
  65. Size: fi.Size(),
  66. From: from,
  67. status: fmt.Sprintf("using existing layer %s", digest),
  68. }, nil
  69. }
  70. func (l *Layer) Open() (io.ReadSeekCloser, error) {
  71. blob, err := GetBlobsPath(l.Digest)
  72. if err != nil {
  73. return nil, err
  74. }
  75. return os.Open(blob)
  76. }