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
|
package persist
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
log "github.com/crc-org/crc/v2/pkg/crc/logging"
"github.com/crc-org/crc/v2/pkg/libmachine/host"
)
type Filestore struct {
MachinesDir string
}
func NewFilestore(path string) *Filestore {
return &Filestore{
MachinesDir: filepath.Join(path, "machines"),
}
}
func (s Filestore) saveToFile(data []byte, file string) error {
if _, err := os.Stat(file); os.IsNotExist(err) {
return os.WriteFile(file, data, 0600)
}
tmpfi, err := os.CreateTemp(filepath.Dir(file), "config.json.tmp")
if err != nil {
return err
}
defer os.Remove(tmpfi.Name())
if err = os.WriteFile(tmpfi.Name(), data, 0600); err != nil {
return err
}
if err = tmpfi.Close(); err != nil {
return err
}
if err = os.Remove(file); err != nil {
return err
}
err = os.Rename(tmpfi.Name(), file)
return err
}
func (s Filestore) Save(host *host.Host) error {
data, err := json.MarshalIndent(host, "", " ")
if err != nil {
return err
}
hostPath := filepath.Join(s.MachinesDir, host.Name)
// Ensure that the directory we want to save to exists.
if err := os.MkdirAll(hostPath, 0700); err != nil {
return err
}
return s.saveToFile(data, filepath.Join(hostPath, "config.json"))
}
func (s Filestore) Remove(name string) error {
hostPath := filepath.Join(s.MachinesDir, name)
return os.RemoveAll(hostPath)
}
func (s Filestore) SetExists(name string) error {
filename := filepath.Join(s.MachinesDir, name, fmt.Sprintf(".%s-exist", name))
file, err := os.OpenFile(filename, os.O_RDONLY|os.O_CREATE, 0666)
if err != nil {
return err
}
file.Close()
log.Debugf("Created %s", filename)
return nil
}
func (s Filestore) Exists(name string) (bool, error) {
filename := filepath.Join(s.MachinesDir, name, fmt.Sprintf(".%s-exist", name))
_, err := os.Stat(filename)
log.Debugf("Checking file: %s", filename)
if os.IsNotExist(err) {
return false, nil
} else if err == nil {
return true, nil
}
return false, err
}
func (s Filestore) Load(name string) (*host.Host, error) {
hostPath := filepath.Join(s.MachinesDir, name)
if _, err := os.Stat(hostPath); os.IsNotExist(err) {
return nil, fmt.Errorf("machine %s does not exist", name)
}
data, err := os.ReadFile(filepath.Join(s.MachinesDir, name, "config.json"))
if err != nil {
return nil, err
}
return host.MigrateHost(name, data)
}
|