forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
empty_dir_quota.go
104 lines (85 loc) · 3.23 KB
/
empty_dir_quota.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
package emptydir
import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/types"
"k8s.io/kubernetes/pkg/volume"
)
var _ volume.VolumePlugin = &EmptyDirQuotaPlugin{}
var _ volume.Builder = &emptyDirQuotaBuilder{}
// EmptyDirQuotaPlugin is a simple wrapper for the k8s empty dir plugin builder.
type EmptyDirQuotaPlugin struct {
// wrapped is the actual k8s emptyDir volume plugin we will pass method calls to.
Wrapped volume.VolumePlugin
// The default quota to apply to each node:
Quota resource.Quantity
// QuotaApplicator is passed to actual volume builders so they can apply
// quota for the supported filesystem.
QuotaApplicator QuotaApplicator
}
func (plugin *EmptyDirQuotaPlugin) NewBuilder(spec *volume.Spec, pod *api.Pod, opts volume.VolumeOptions) (volume.Builder, error) {
volBuilder, err := plugin.Wrapped.NewBuilder(spec, pod, opts)
if err != nil {
return volBuilder, err
}
// Because we cannot access several fields on the k8s emptyDir struct, and
// we do not wish to modify k8s code for this, we have to grab a reference
// to them ourselves.
// This logic is the same as k8s.io/kubernetes/pkg/volume/empty_dir:
medium := api.StorageMediumDefault
if spec.Volume.EmptyDir != nil { // Support a non-specified source as EmptyDir.
medium = spec.Volume.EmptyDir.Medium
}
// Wrap the builder object with our own to add quota functionality:
wrapperEmptyDir := &emptyDirQuotaBuilder{
wrapped: volBuilder,
pod: pod,
medium: medium,
quota: plugin.Quota,
quotaApplicator: plugin.QuotaApplicator,
}
return wrapperEmptyDir, err
}
func (plugin *EmptyDirQuotaPlugin) Init(host volume.VolumeHost) error {
return plugin.Wrapped.Init(host)
}
func (plugin *EmptyDirQuotaPlugin) Name() string {
return plugin.Wrapped.Name()
}
func (plugin *EmptyDirQuotaPlugin) CanSupport(spec *volume.Spec) bool {
return plugin.Wrapped.CanSupport(spec)
}
func (plugin *EmptyDirQuotaPlugin) NewCleaner(volName string, podUID types.UID) (volume.Cleaner, error) {
return plugin.Wrapped.NewCleaner(volName, podUID)
}
// emptyDirQuotaBuilder is a wrapper plugin builder for the k8s empty dir builder itself.
// This plugin just extends and adds the functionality to apply a
// quota for the pods FSGroup on an XFS filesystem.
type emptyDirQuotaBuilder struct {
wrapped volume.Builder
pod *api.Pod
medium api.StorageMedium
quota resource.Quantity
quotaApplicator QuotaApplicator
}
// Must implement SetUp as well, otherwise the internal Builder.SetUp calls its
// own SetUpAt method, not the one we need.
func (edq *emptyDirQuotaBuilder) SetUp(fsGroup *int64) error {
return edq.SetUpAt(edq.GetPath(), fsGroup)
}
func (edq *emptyDirQuotaBuilder) SetUpAt(dir string, fsGroup *int64) error {
err := edq.wrapped.SetUpAt(dir, fsGroup)
if err == nil {
err = edq.quotaApplicator.Apply(dir, edq.medium, edq.pod, fsGroup, edq.quota)
}
return err
}
func (edq *emptyDirQuotaBuilder) GetAttributes() volume.Attributes {
return edq.wrapped.GetAttributes()
}
func (edq *emptyDirQuotaBuilder) GetMetrics() (*volume.Metrics, error) {
return edq.wrapped.GetMetrics()
}
func (edq *emptyDirQuotaBuilder) GetPath() string {
return edq.wrapped.GetPath()
}