/
accelerate.go
98 lines (85 loc) · 2.84 KB
/
accelerate.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
package accelerator
import (
"fmt"
"github.com/caicloud/nirvana/log"
"github.com/caicloud/cyclone/pkg/apis/cyclone/v1alpha1"
api "github.com/caicloud/cyclone/pkg/apis/cyclone/v1alpha1"
"github.com/caicloud/cyclone/pkg/meta"
"github.com/caicloud/cyclone/pkg/server/biz/usage"
"github.com/caicloud/cyclone/pkg/server/common"
"github.com/caicloud/cyclone/pkg/server/handler"
)
// CacheSizeLimit is cache size limit, it's percentage of the total PVC size.
const CacheSizeLimit = 0.8
// Accelerator ...
type Accelerator struct {
// tenant name
tenant string
// project the wfr belongs to
project string
// wfr represents a workflowrun
wfr *api.WorkflowRun
// reporter reports PVC usage used for workflow in the tenant
reporter usage.PVCReporter
}
// NewAccelerator new an accelerator
func NewAccelerator(tenant, project string, wfr *api.WorkflowRun) *Accelerator {
reporter, err := usage.NewPVCReporter(handler.K8sClient, tenant)
if err != nil {
log.Warningf("Create pvc reporter for tenant %s error: %v", tenant, err)
}
return &Accelerator{
tenant: tenant,
wfr: wfr,
project: project,
reporter: reporter,
}
}
// Accelerate will check if the workflowrun has label 'workflowrun.cyclone.dev/acceleration=true',
// True will mount some volumes into all stages under the related workflow to cache building dependencies.
// volumes including:
// - '/root/.m2' maven dependency path
// - '/root/.gradle' gradle dependency path
// - '/root/.npm' npm dependency path
func (a *Accelerator) Accelerate() {
if !a.allowed() {
return
}
if a.wfr.Labels != nil && a.wfr.Labels[meta.LabelWorkflowRunAcceleration] == meta.LabelValueTrue {
a.wfr.Spec.PresetVolumes = append(a.wfr.Spec.PresetVolumes, []v1alpha1.PresetVolume{
{
Type: v1alpha1.PresetVolumeTypePVC,
Path: fmt.Sprintf("%s/%s/m2", common.CachePrefixPath, a.project),
MountPath: "/root/.m2",
},
{
Type: v1alpha1.PresetVolumeTypePVC,
Path: fmt.Sprintf("%s/%s/gradle", common.CachePrefixPath, a.project),
MountPath: "/root/.gradle",
},
{
Type: v1alpha1.PresetVolumeTypePVC,
Path: fmt.Sprintf("%s/%s/npm", common.CachePrefixPath, a.project),
MountPath: "/root/.npm",
},
}...)
}
}
// allowed determines whether it's allowed to open acceleration for the workflow execution. For the moment,
// only PVC storage constraint is enforced.
func (a *Accelerator) allowed() bool {
if a.reporter == nil {
return true
}
used, err := a.reporter.UsedPercentage("caches")
if err != nil {
log.Warningf("Get caches usage error: %v", err)
return true
}
log.Infof("caches used %.2f PVC storage in tenant %s", used, a.tenant)
if used >= float64(CacheSizeLimit) {
log.Warningf("caches used %.2f PVC storage, exceeds limit %.2f, will stop acceleration, tenant: %s", used, CacheSizeLimit, a.tenant)
return false
}
return true
}