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
package clusterprovider
import (
"encoding/json"
"errors"
"fmt"
"io/fs"
"os"
"path/filepath"
"github.com/johnandersen777/socialweb-computer-kcp/internal/scale"
)
const AddOnFieldManager = "socialweb-addons"
const AddOnBaselineName = "addon-baseline.json"
const addOnBaselineMode = 0o600
func AddOnBaselinePath(dataDir string) string {
return filepath.Join(dataDir, AddOnBaselineName)
}
func ReadAddOnBaseline(dataDir string) (scale.Baseline, bool, error) {
path := AddOnBaselinePath(dataDir)
raw, err := os.ReadFile(path)
if errors.Is(err, fs.ErrNotExist) {
return scale.Baseline{}, false, nil
}
if err != nil {
return scale.Baseline{}, false, fmt.Errorf("clusterprovider: reading the add-on baseline at %s: %w", path, err)
}
var b scale.Baseline
if err := json.Unmarshal(raw, &b); err != nil {
return scale.Baseline{}, false, fmt.Errorf("clusterprovider: the add-on baseline at %s is not JSON: %v", path, err)
}
return b, true, nil
}
func WriteAddOnBaseline(dataDir string, b scale.Baseline) error {
path := AddOnBaselinePath(dataDir)
body, err := json.MarshalIndent(b, "", " ")
if err != nil {
return fmt.Errorf("clusterprovider: encoding the add-on baseline for %s: %w", path, err)
}
tmp, err := os.CreateTemp(dataDir, AddOnBaselineName+".")
if err != nil {
return fmt.Errorf("clusterprovider: a temporary file beside %s: %w", path, err)
}
defer func() { _ = os.Remove(tmp.Name()) }()
if err := tmp.Chmod(addOnBaselineMode); err != nil {
_ = tmp.Close()
return fmt.Errorf("clusterprovider: the mode of %s: %w", tmp.Name(), err)
}
if _, err := tmp.Write(append(body, '\n')); err != nil {
_ = tmp.Close()
return fmt.Errorf("clusterprovider: writing %s: %w", tmp.Name(), err)
}
if err := tmp.Close(); err != nil {
return fmt.Errorf("clusterprovider: closing %s: %w", tmp.Name(), err)
}
if err := os.Rename(tmp.Name(), path); err != nil {
return fmt.Errorf("clusterprovider: renaming %s over %s: %w", tmp.Name(), path, err)
}
return nil
}