-
Notifications
You must be signed in to change notification settings - Fork 85
/
config.go
194 lines (163 loc) · 5.29 KB
/
config.go
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
package config
import (
"context"
"crypto/rand"
"encoding/base64"
"errors"
"fmt"
"os"
"path/filepath"
"time"
"github.com/bacalhau-project/bacalhau/pkg/storage/util"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/rs/zerolog/log"
)
func DevstackShouldWriteEnvFile() bool {
return DevstackEnvFile() != ""
}
func DevstackEnvFile() string {
return os.Getenv("DEVSTACK_ENV_FILE")
}
func DevstackGetShouldPrintInfo() bool {
return os.Getenv("DEVSTACK_PRINT_INFO") != ""
}
func DevstackSetShouldPrintInfo() {
os.Setenv("DEVSTACK_PRINT_INFO", "1")
}
func ShouldKeepStack() bool {
return os.Getenv("KEEP_STACK") != ""
}
func GetStoragePath() string {
storagePath := os.Getenv("BACALHAU_STORAGE_PATH")
if storagePath == "" {
storagePath = os.TempDir()
}
return storagePath
}
func GetAPIHost() string {
return os.Getenv("BACALHAU_HOST")
}
func GetAPIPort() string {
return os.Getenv("BACALHAU_PORT")
}
type contextKey int
const (
getVolumeSizeRequestTimeoutKey contextKey = iota
)
const (
// by default we wait 2 minutes for the IPFS network to resolve a CID
// tests will override this using config.SetVolumeSizeRequestTimeout(2)
getVolumeSizeRequestTimeout = 2 * time.Minute
)
// how long do we wait for a volume size request to timeout
// if a non-existing cid is asked for - the dockerIPFS.IPFSClient.GetCidSize(ctx, volume.Cid)
// function will hang for a long time - so we wrap that call in a timeout
// for tests - we only want to wait for 2 seconds because everything is on a local network
// in prod - we want to wait longer because we might be running a job that is
// using non-local CIDs
// the tests are expected to call SetVolumeSizeRequestTimeout to reduce this timeout
func GetVolumeSizeRequestTimeout(ctx context.Context) time.Duration {
value := ctx.Value(getVolumeSizeRequestTimeoutKey)
if value == nil {
value = getVolumeSizeRequestTimeout
}
return value.(time.Duration)
}
func SetVolumeSizeRequestTimeout(ctx context.Context, value time.Duration) context.Context {
return context.WithValue(ctx, getVolumeSizeRequestTimeoutKey, value)
}
// by default we wait 5 minutes for a URL to download
// tests will override this using config.SetDownloadURLRequestTimeoutSeconds(2)
var downloadURLRequestTimeoutSeconds int64 = 300
// how long do we wait for a URL to download
func GetDownloadURLRequestTimeout() time.Duration {
return time.Duration(downloadURLRequestTimeoutSeconds) * time.Second
}
// how many times do we try to download a URL
var downloadURLRequestRetries = 3
// how long do we wait for a URL to download
func GetDownloadURLRequestRetries() int {
return downloadURLRequestRetries
}
func GetLibp2pTracerPath() string {
configPath := GetConfigPath()
return filepath.Join(configPath, "bacalhau-libp2p-tracer.json")
}
func GetEventTracerPath() string {
configPath := GetConfigPath()
return filepath.Join(configPath, "bacalhau-event-tracer.json")
}
func GetConfigPath() string {
suffix := ".bacalhau"
env := os.Getenv("BACALHAU_PATH")
var d string
if env == "" {
// e.g. /home/francesca/.bacalhau
dirname, err := os.UserHomeDir()
if err != nil {
log.Fatal().Err(err).Send()
}
d = filepath.Join(dirname, suffix)
} else {
// e.g. /data/.bacalhau
d = filepath.Join(env, suffix)
}
// create dir if not exists
if err := os.MkdirAll(d, util.OS_USER_RWX); err != nil {
log.Fatal().Err(err).Send()
}
return d
}
const BitsForKeyPair = 2048
func GetPrivateKey(keyName string) (crypto.PrivKey, error) {
configPath := GetConfigPath()
// We include the port in the filename so that in devstack multiple nodes
// running on the same host get different identities
privKeyPath := filepath.Join(configPath, keyName)
if _, err := os.Stat(privKeyPath); errors.Is(err, os.ErrNotExist) {
// Private key does not exist - create and write it
// Creates a new RSA key pair for this host.
prvKey, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, BitsForKeyPair, rand.Reader)
if err != nil {
log.Error().Err(err)
return nil, err
}
keyOut, err := os.OpenFile(privKeyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, util.OS_USER_RW)
if err != nil {
return nil, fmt.Errorf("failed to open key.pem for writing: %v", err)
}
privBytes, err := crypto.MarshalPrivateKey(prvKey)
if err != nil {
return nil, fmt.Errorf("unable to marshal private key: %v", err)
}
// base64 encode privBytes
b64 := base64.StdEncoding.EncodeToString(privBytes)
_, err = keyOut.WriteString(b64 + "\n")
if err != nil {
return nil, fmt.Errorf("failed to write to key file: %v", err)
}
if err := keyOut.Close(); err != nil {
return nil, fmt.Errorf("error closing key file: %v", err)
}
log.Debug().Msgf("wrote %s", privKeyPath)
}
// Now that we've ensured the private key is written to disk, read it! This
// ensures that loading it works even in the case where we've just created
// it.
// read the private key
keyBytes, err := os.ReadFile(privKeyPath)
if err != nil {
return nil, fmt.Errorf("failed to read private key: %v", err)
}
// base64 decode keyBytes
b64, err := base64.StdEncoding.DecodeString(string(keyBytes))
if err != nil {
return nil, fmt.Errorf("failed to decode private key: %v", err)
}
// parse the private key
prvKey, err := crypto.UnmarshalPrivateKey(b64)
if err != nil {
return nil, fmt.Errorf("failed to parse private key: %v", err)
}
return prvKey, nil
}