disk.go

v1.3.5
Doc Versions Source
1
package storage
2
3
import (
4
	"context"
5
	"encoding/json"
6
	"errors"
7
	"os"
8
	"path/filepath"
9
)
10
11
type diskMeta struct {
12
	ContentType string `json:"content_type"`
13
}
14
15
// DiskStorage stores artifacts as files on the local filesystem.
16
type DiskStorage struct {
17
	root string
18
}
19
20
// NewDiskStorage creates a disk-based storage under root.
21
func NewDiskStorage(root string) (*DiskStorage, error) {
22
	if err := os.MkdirAll(root, 0o755); err != nil {
23
		return nil, err
24
	}
25
	return &DiskStorage{root: root}, nil
26
}
27
28
func (d *DiskStorage) path(key string) string {
29
	return filepath.Join(d.root, filepath.FromSlash(key))
30
}
31
32
func (d *DiskStorage) metaPath(key string) string {
33
	return d.path(key) + ".meta"
34
}
35
36
func (d *DiskStorage) Get(_ context.Context, key string) ([]byte, string, error) {
37
	data, err := os.ReadFile(d.path(key))
38
	if err != nil {
39
		if errors.Is(err, os.ErrNotExist) {
40
			return nil, "", ErrNotFound
41
		}
42
		return nil, "", err
43
	}
44
45
	ct := ""
46
	if metaData, err := os.ReadFile(d.metaPath(key)); err == nil {
47
		var m diskMeta
48
		if json.Unmarshal(metaData, &m) == nil {
49
			ct = m.ContentType
50
		}
51
	}
52
53
	return data, ct, nil
54
}
55
56
func (d *DiskStorage) Put(_ context.Context, key string, data []byte, contentType string) error {
57
	p := d.path(key)
58
	if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil {
59
		return err
60
	}
61
62
	if err := os.WriteFile(p, data, 0o644); err != nil {
63
		return err
64
	}
65
66
	if contentType != "" {
67
		meta, _ := json.Marshal(diskMeta{ContentType: contentType})
68
		os.WriteFile(d.metaPath(key), meta, 0o644)
69
	}
70
71
	return nil
72
}
73
74
func (d *DiskStorage) BucketStats(_ context.Context) (objects int64, sizeBytes int64, err error) {
75
	err = filepath.Walk(d.root, func(path string, info os.FileInfo, err error) error {
76
		if err != nil {
77
			return err
78
		}
79
		if info.IsDir() || filepath.Ext(path) == ".meta" {
80
			return nil
81
		}
82
		objects++
83
		sizeBytes += info.Size()
84
		return nil
85
	})
86
	return
87
}
88

Source Files