forked from irinazheltisheva/powergate
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapi_actions.go
More file actions
158 lines (142 loc) · 4.58 KB
/
api_actions.go
File metadata and controls
158 lines (142 loc) · 4.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package api
import (
"context"
"fmt"
"io"
"github.com/ipfs/go-cid"
"github.com/textileio/powergate/ffs"
"github.com/textileio/powergate/ffs/scheduler"
)
// PushStorageConfig push a new configuration for the Cid in the Hot and
// Cold layer. If WithOverride opt isn't set it errors with ErrMustOverrideConfig.
func (i *API) PushStorageConfig(c cid.Cid, opts ...PushStorageConfigOption) (ffs.JobID, error) {
i.lock.Lock()
defer i.lock.Unlock()
cfg := PushStorageConfigConfig{Config: i.cfg.DefaultStorageConfig}
for _, opt := range opts {
if err := opt(&cfg); err != nil {
return ffs.EmptyJobID, fmt.Errorf("config option: %s", err)
}
}
if !cfg.OverrideConfig {
_, err := i.is.getStorageConfig(c)
if err == nil {
return ffs.EmptyJobID, ErrMustOverrideConfig
}
if err != ErrNotFound {
return ffs.EmptyJobID, fmt.Errorf("getting cid config: %s", err)
}
}
if err := cfg.Config.Validate(); err != nil {
return ffs.EmptyJobID, err
}
if err := i.ensureValidColdCfg(cfg.Config.Cold); err != nil {
return ffs.EmptyJobID, err
}
jid, err := i.sched.PushConfig(i.cfg.ID, c, cfg.Config)
if err != nil {
return ffs.EmptyJobID, fmt.Errorf("scheduling cid %s: %s", c, err)
}
if err := i.is.putStorageConfig(c, cfg.Config); err != nil {
return ffs.EmptyJobID, fmt.Errorf("saving new config for cid %s: %s", c, err)
}
return jid, nil
}
// Remove removes a Cid from being tracked as an active storage. The Cid should have
// both Hot and Cold storage disabled, if that isn't the case it will return ErrActiveInStorage.
func (i *API) Remove(c cid.Cid) error {
i.lock.Lock()
defer i.lock.Unlock()
cfg, err := i.is.getStorageConfig(c)
if err == ErrNotFound {
return err
}
if err != nil {
return fmt.Errorf("getting cid config from store: %s", err)
}
if cfg.Hot.Enabled || cfg.Cold.Enabled {
return ErrActiveInStorage
}
if err := i.sched.Untrack(c); err != nil {
return fmt.Errorf("untracking from scheduler: %s", err)
}
if err := i.is.removeStorageConfig(c); err != nil {
return fmt.Errorf("deleting replaced cid config: %s", err)
}
return nil
}
// Replace pushes a StorageConfig for c2 equal to that of c1, and removes c1. This operation
// is more efficient than manually removing and adding in two separate operations.
// c1 and c2 must not be equal.
func (i *API) Replace(c1 cid.Cid, c2 cid.Cid) (ffs.JobID, error) {
i.lock.Lock()
defer i.lock.Unlock()
if c1.Equals(c2) {
return ffs.EmptyJobID, fmt.Errorf("the old and new cid should be different")
}
cfg, err := i.is.getStorageConfig(c1)
if err == ErrNotFound {
return ffs.EmptyJobID, ErrReplacedCidNotFound
}
if err != nil {
return ffs.EmptyJobID, fmt.Errorf("getting replaced cid config: %s", err)
}
if err := i.ensureValidColdCfg(cfg.Cold); err != nil {
return ffs.EmptyJobID, err
}
jid, err := i.sched.PushReplace(i.cfg.ID, c2, cfg, c1)
if err != nil {
return ffs.EmptyJobID, fmt.Errorf("scheduling replacement %s to %s: %s", c1, c2, err)
}
if err := i.is.putStorageConfig(c2, cfg); err != nil {
return ffs.EmptyJobID, fmt.Errorf("saving new config for cid %s: %s", c2, err)
}
if err := i.is.removeStorageConfig(c1); err != nil {
return ffs.EmptyJobID, fmt.Errorf("deleting replaced cid config: %s", err)
}
return jid, nil
}
// Get returns an io.Reader for reading a stored Cid from the Hot Storage.
func (i *API) Get(ctx context.Context, c cid.Cid) (io.Reader, error) {
if !c.Defined() {
return nil, fmt.Errorf("cid is undefined")
}
conf, err := i.is.getStorageConfig(c)
if err != nil {
return nil, fmt.Errorf("getting cid config: %s", err)
}
if !conf.Hot.Enabled {
return nil, ErrHotStorageDisabled
}
r, err := i.sched.GetCidFromHot(ctx, c)
if err != nil {
return nil, fmt.Errorf("getting from hot layer %s: %s", c, err)
}
return r, nil
}
// Show returns the information about a stored Cid. If no information is available,
// since the Cid was never stored, it returns ErrNotFound.
func (i *API) Show(c cid.Cid) (ffs.CidInfo, error) {
inf, err := i.sched.GetCidInfo(c)
if err == scheduler.ErrNotFound {
return inf, ErrNotFound
}
if err != nil {
return inf, fmt.Errorf("getting cid information: %s", err)
}
return inf, nil
}
// CancelJob cancels an executing Job. If no Job is executing
// with that JobID, it won't fail.
func (i *API) CancelJob(jid ffs.JobID) error {
if err := i.sched.Cancel(jid); err != nil {
return fmt.Errorf("canceling job %s: %s", jid, err)
}
return nil
}
func (i *API) ensureValidColdCfg(cfg ffs.ColdConfig) error {
if cfg.Enabled && !i.isManagedAddress(cfg.Filecoin.Addr) {
return fmt.Errorf("%v is not managed by ffs instance", cfg.Filecoin.Addr)
}
return nil
}