-
Notifications
You must be signed in to change notification settings - Fork 3
/
flavor.go
127 lines (106 loc) · 2.51 KB
/
flavor.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
package lochness
import (
"encoding/json"
"errors"
"path/filepath"
"github.com/mistifyio/lochness/pkg/kv"
"github.com/pborman/uuid"
)
var (
// FlavorPath is the path in the config store
FlavorPath = "lochness/flavors/"
)
type (
// Flavor defines the virtual resources for a guest
Flavor struct {
context *Context
modifiedIndex uint64
ID string `json:"id"`
Image string `json:"image"`
Metadata map[string]string `json:"metadata"`
Resources
}
// Flavors is an alias to a slice of *Flavor
Flavors []*Flavor
// Resources represents compute resources
Resources struct {
Memory uint64 `json:"memory"` // memory in MB
Disk uint64 `json:"disk"` // disk in MB
CPU uint32 `json:"cpu"` // virtual cpus
}
)
// NewFlavor creates a blank Flavor
func (c *Context) NewFlavor() *Flavor {
f := &Flavor{
context: c,
ID: uuid.New(),
Metadata: make(map[string]string),
}
return f
}
// Flavor fetches a single Flavor from the config store
func (c *Context) Flavor(id string) (*Flavor, error) {
var err error
id, err = canonicalizeUUID(id)
if err != nil {
return nil, err
}
f := &Flavor{
context: c,
ID: id,
}
err = f.Refresh()
if err != nil {
return nil, err
}
return f, nil
}
// key is a helper to generate the config store key
func (f *Flavor) key() string {
return filepath.Join(FlavorPath, f.ID, "metadata")
}
// fromResponse is a helper to unmarshal a Flavor
func (f *Flavor) fromResponse(value kv.Value) error {
f.modifiedIndex = value.Index
return json.Unmarshal(value.Data, &f)
}
// Refresh reloads from the data store
func (f *Flavor) Refresh() error {
resp, err := f.context.kv.Get(f.key())
if err != nil {
return err
}
return f.fromResponse(resp)
}
// Validate ensures a Flavor has reasonable data. It currently does nothing.
func (f *Flavor) Validate() error {
if f.ID == "" {
return errors.New("flavor ID required")
}
if uuid.Parse(f.ID) == nil {
return errors.New("flavor ID must be uuid")
}
if f.Image == "" {
return errors.New("flavor image required")
}
if uuid.Parse(f.Image) == nil {
return errors.New("flavor image must be uuid")
}
return nil
}
// Save persists a Flavor.
// It will call Validate.
func (f *Flavor) Save() error {
if err := f.Validate(); err != nil {
return err
}
v, err := json.Marshal(f)
if err != nil {
return err
}
index, err := f.context.kv.Update(f.key(), kv.Value{Data: v, Index: f.modifiedIndex})
if err == nil {
f.modifiedIndex = index
}
return err
}