-
Notifications
You must be signed in to change notification settings - Fork 4
/
capacity.go
112 lines (102 loc) · 3.33 KB
/
capacity.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
/*******************************************************************************
*
* Copyright 2019-2024 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You should have received a copy of the License along with this
* program. If not, you may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*******************************************************************************/
package nova
import (
"fmt"
"github.com/sapcc/limes/internal/core"
)
// PartialCapacity describes compute capacity at a level below the entire
// cluster (e.g. for a single hypervisor, aggregate or AZ).
type PartialCapacity struct {
VCPUs PartialCapacityMetric
MemoryMB PartialCapacityMetric
LocalGB PartialCapacityMetric
RunningVMs uint64
MatchingAggregates map[string]bool
Subcapacities []any // only filled on AZ level
}
func (c *PartialCapacity) Add(other PartialCapacity) {
c.VCPUs.Capacity += other.VCPUs.Capacity
c.VCPUs.Usage += other.VCPUs.Usage
c.MemoryMB.Capacity += other.MemoryMB.Capacity
c.MemoryMB.Usage += other.MemoryMB.Usage
c.LocalGB.Capacity += other.LocalGB.Capacity
c.LocalGB.Usage += other.LocalGB.Usage
c.RunningVMs += other.RunningVMs
if c.MatchingAggregates == nil {
c.MatchingAggregates = make(map[string]bool)
}
for aggrName, matches := range other.MatchingAggregates {
if matches {
c.MatchingAggregates[aggrName] = true
}
}
}
func (c PartialCapacity) CappedToUsage() PartialCapacity {
return PartialCapacity{
VCPUs: c.VCPUs.CappedToUsage(),
MemoryMB: c.MemoryMB.CappedToUsage(),
LocalGB: c.LocalGB.CappedToUsage(),
RunningVMs: c.RunningVMs,
MatchingAggregates: c.MatchingAggregates,
Subcapacities: c.Subcapacities,
}
}
func (c PartialCapacity) IntoCapacityData(resourceName string, maxRootDiskSize float64, subcapacities []any) core.CapacityData {
switch resourceName {
case "cores":
return core.CapacityData{
Capacity: c.VCPUs.Capacity,
Usage: &c.VCPUs.Usage,
Subcapacities: subcapacities,
}
case "ram":
return core.CapacityData{
Capacity: c.MemoryMB.Capacity,
Usage: &c.MemoryMB.Usage,
Subcapacities: subcapacities,
}
case "instances":
amount := 10000 * uint64(len(c.MatchingAggregates))
if maxRootDiskSize != 0 {
maxAmount := uint64(float64(c.LocalGB.Capacity) / maxRootDiskSize)
if amount > maxAmount {
amount = maxAmount
}
}
return core.CapacityData{
Capacity: amount,
Usage: &c.RunningVMs,
Subcapacities: subcapacities,
}
default:
panic(fmt.Sprintf("called with unknown resourceName %q", resourceName))
}
}
// PartialCapacityMetric appears in type PartialCapacity.
type PartialCapacityMetric struct {
Capacity uint64
Usage uint64
}
func (m PartialCapacityMetric) CappedToUsage() PartialCapacityMetric {
return PartialCapacityMetric{
Capacity: min(m.Capacity, m.Usage),
Usage: m.Usage,
}
}