Update go dependencies
This commit is contained in:
parent
293223eea0
commit
b7a799bf82
432 changed files with 37346 additions and 25783 deletions
4
vendor/k8s.io/kubernetes/pkg/BUILD
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/BUILD
generated
vendored
|
|
@ -50,7 +50,6 @@ filegroup(
|
|||
"//pkg/apis/storage:all-srcs",
|
||||
"//pkg/auth/authorizer/abac:all-srcs",
|
||||
"//pkg/auth/nodeidentifier:all-srcs",
|
||||
"//pkg/bootstrap/api:all-srcs",
|
||||
"//pkg/capabilities:all-srcs",
|
||||
"//pkg/client/chaosclient:all-srcs",
|
||||
"//pkg/client/clientset_generated/internalclientset:all-srcs",
|
||||
|
|
@ -77,7 +76,6 @@ filegroup(
|
|||
"//pkg/client/metrics/prometheus:all-srcs",
|
||||
"//pkg/client/testdata:all-srcs",
|
||||
"//pkg/client/tests:all-srcs",
|
||||
"//pkg/client/unversioned:all-srcs",
|
||||
"//pkg/cloudprovider:all-srcs",
|
||||
"//pkg/controller:all-srcs",
|
||||
"//pkg/credentialprovider:all-srcs",
|
||||
|
|
@ -104,7 +102,7 @@ filegroup(
|
|||
"//pkg/version:all-srcs",
|
||||
"//pkg/volume:all-srcs",
|
||||
"//pkg/watch/json:all-srcs",
|
||||
"//pkg/watch/versioned:all-srcs",
|
||||
"//pkg/windows/service:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/api/service/BUILD
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/api/service/BUILD
generated
vendored
|
|
@ -20,7 +20,6 @@ go_test(
|
|||
name = "go_default_test",
|
||||
srcs = ["util_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/api/service",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/util/net/sets:go_default_library",
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/api/v1/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/api/v1/OWNERS
generated
vendored
|
|
@ -27,7 +27,6 @@ reviewers:
|
|||
- ncdc
|
||||
- tallclair
|
||||
- eparis
|
||||
- timothysc
|
||||
- piosz
|
||||
- jsafrane
|
||||
- dims
|
||||
|
|
|
|||
2
vendor/k8s.io/kubernetes/pkg/api/v1/pod/BUILD
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/api/v1/pod/BUILD
generated
vendored
|
|
@ -21,8 +21,8 @@ go_test(
|
|||
name = "go_default_test",
|
||||
srcs = ["util_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/api/v1/pod",
|
||||
deps = [
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
|
||||
|
|
|
|||
2
vendor/k8s.io/kubernetes/pkg/api/v1/pod/util.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/api/v1/pod/util.go
generated
vendored
|
|
@ -238,7 +238,7 @@ func IsPodReady(pod *v1.Pod) bool {
|
|||
return IsPodReadyConditionTrue(pod.Status)
|
||||
}
|
||||
|
||||
// IsPodReady retruns true if a pod is ready; false otherwise.
|
||||
// IsPodReady returns true if a pod is ready; false otherwise.
|
||||
func IsPodReadyConditionTrue(status v1.PodStatus) bool {
|
||||
condition := GetPodReadyCondition(status)
|
||||
return condition != nil && condition.Status == v1.ConditionTrue
|
||||
|
|
|
|||
116
vendor/k8s.io/kubernetes/pkg/api/v1/pod/util_test.go
generated
vendored
116
vendor/k8s.io/kubernetes/pkg/api/v1/pod/util_test.go
generated
vendored
|
|
@ -22,6 +22,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
|
@ -404,3 +405,118 @@ func TestIsPodAvailable(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetContainerStatus(t *testing.T) {
|
||||
type ExpectedStruct struct {
|
||||
status v1.ContainerStatus
|
||||
exists bool
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
status []v1.ContainerStatus
|
||||
name string
|
||||
expected ExpectedStruct
|
||||
desc string
|
||||
}{
|
||||
{
|
||||
status: []v1.ContainerStatus{{Name: "test1", Ready: false, Image: "image1"}, {Name: "test2", Ready: true, Image: "image1"}},
|
||||
name: "test1",
|
||||
expected: ExpectedStruct{status: v1.ContainerStatus{Name: "test1", Ready: false, Image: "image1"}, exists: true},
|
||||
desc: "retrieve ContainerStatus with Name=\"test1\"",
|
||||
},
|
||||
{
|
||||
status: []v1.ContainerStatus{{Name: "test2", Ready: false, Image: "image2"}},
|
||||
name: "test1",
|
||||
expected: ExpectedStruct{status: v1.ContainerStatus{}, exists: false},
|
||||
desc: "no matching ContainerStatus with Name=\"test1\"",
|
||||
},
|
||||
{
|
||||
status: []v1.ContainerStatus{{Name: "test3", Ready: false, Image: "image3"}},
|
||||
name: "",
|
||||
expected: ExpectedStruct{status: v1.ContainerStatus{}, exists: false},
|
||||
desc: "retrieve an empty ContainerStatus with container name empty",
|
||||
},
|
||||
{
|
||||
status: nil,
|
||||
name: "",
|
||||
expected: ExpectedStruct{status: v1.ContainerStatus{}, exists: false},
|
||||
desc: "retrieve an empty ContainerStatus with status nil",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
resultStatus, exists := GetContainerStatus(test.status, test.name)
|
||||
assert.Equal(t, test.expected.status, resultStatus, "GetContainerStatus: "+test.desc)
|
||||
assert.Equal(t, test.expected.exists, exists, "GetContainerStatus: "+test.desc)
|
||||
|
||||
resultStatus = GetExistingContainerStatus(test.status, test.name)
|
||||
assert.Equal(t, test.expected.status, resultStatus, "GetExistingContainerStatus: "+test.desc)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdatePodCondition(t *testing.T) {
|
||||
time := metav1.Now()
|
||||
|
||||
podStatus := v1.PodStatus{
|
||||
Conditions: []v1.PodCondition{
|
||||
{
|
||||
Type: v1.PodReady,
|
||||
Status: v1.ConditionTrue,
|
||||
Reason: "successfully",
|
||||
Message: "sync pod successfully",
|
||||
LastProbeTime: time,
|
||||
LastTransitionTime: metav1.NewTime(time.Add(1000)),
|
||||
},
|
||||
},
|
||||
}
|
||||
tests := []struct {
|
||||
status *v1.PodStatus
|
||||
conditions v1.PodCondition
|
||||
expected bool
|
||||
desc string
|
||||
}{
|
||||
{
|
||||
status: &podStatus,
|
||||
conditions: v1.PodCondition{
|
||||
Type: v1.PodReady,
|
||||
Status: v1.ConditionTrue,
|
||||
Reason: "successfully",
|
||||
Message: "sync pod successfully",
|
||||
LastProbeTime: time,
|
||||
LastTransitionTime: metav1.NewTime(time.Add(1000))},
|
||||
expected: false,
|
||||
desc: "all equal, no update",
|
||||
},
|
||||
{
|
||||
status: &podStatus,
|
||||
conditions: v1.PodCondition{
|
||||
Type: v1.PodScheduled,
|
||||
Status: v1.ConditionTrue,
|
||||
Reason: "successfully",
|
||||
Message: "sync pod successfully",
|
||||
LastProbeTime: time,
|
||||
LastTransitionTime: metav1.NewTime(time.Add(1000))},
|
||||
expected: true,
|
||||
desc: "not equal Type, should get updated",
|
||||
},
|
||||
{
|
||||
status: &podStatus,
|
||||
conditions: v1.PodCondition{
|
||||
Type: v1.PodReady,
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: "successfully",
|
||||
Message: "sync pod successfully",
|
||||
LastProbeTime: time,
|
||||
LastTransitionTime: metav1.NewTime(time.Add(1000))},
|
||||
expected: true,
|
||||
desc: "not equal Status, should get updated",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
var resultStatus bool
|
||||
resultStatus = UpdatePodCondition(test.status, &test.conditions)
|
||||
|
||||
assert.Equal(t, test.expected, resultStatus, test.desc)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/apis/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/OWNERS
generated
vendored
|
|
@ -33,7 +33,6 @@ reviewers:
|
|||
- yifan-gu
|
||||
- eparis
|
||||
- mwielgus
|
||||
- timothysc
|
||||
- feiskyer
|
||||
- soltysh
|
||||
- piosz
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/apis/autoscaling/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/autoscaling/OWNERS
generated
vendored
|
|
@ -8,7 +8,6 @@ reviewers:
|
|||
- erictune
|
||||
- sttts
|
||||
- ncdc
|
||||
- timothysc
|
||||
- piosz
|
||||
- dims
|
||||
- errordeveloper
|
||||
|
|
|
|||
57
vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go
generated
vendored
57
vendor/k8s.io/kubernetes/pkg/apis/autoscaling/types.go
generated
vendored
|
|
@ -111,6 +111,12 @@ var (
|
|||
// Kubernetes, and have special scaling options on top of those available
|
||||
// to normal per-pod metrics (the "pods" source).
|
||||
ResourceMetricSourceType MetricSourceType = "Resource"
|
||||
// ExternalMetricSourceType is a global metric that is not associated
|
||||
// with any Kubernetes object. It allows autoscaling based on information
|
||||
// coming from components running outside of cluster
|
||||
// (for example length of queue in cloud messaging service, or
|
||||
// QPS from loadbalancer running outside of cluster).
|
||||
ExternalMetricSourceType MetricSourceType = "External"
|
||||
)
|
||||
|
||||
// MetricSpec specifies how to scale based on a single metric
|
||||
|
|
@ -136,6 +142,13 @@ type MetricSpec struct {
|
|||
// to normal per-pod metrics using the "pods" source.
|
||||
// +optional
|
||||
Resource *ResourceMetricSource
|
||||
// External refers to a global metric that is not associated
|
||||
// with any Kubernetes object. It allows autoscaling based on information
|
||||
// coming from components running outside of cluster
|
||||
// (for example length of queue in cloud messaging service, or
|
||||
// QPS from loadbalancer running outside of cluster).
|
||||
// +optional
|
||||
External *ExternalMetricSource
|
||||
}
|
||||
|
||||
// ObjectMetricSource indicates how to scale on a metric describing a
|
||||
|
|
@ -184,6 +197,26 @@ type ResourceMetricSource struct {
|
|||
TargetAverageValue *resource.Quantity
|
||||
}
|
||||
|
||||
// ExternalMetricSource indicates how to scale on a metric not associated with
|
||||
// any Kubernetes object (for example length of queue in cloud
|
||||
// messaging service, or QPS from loadbalancer running outside of cluster).
|
||||
type ExternalMetricSource struct {
|
||||
// metricName is the name of the metric in question.
|
||||
MetricName string
|
||||
// MetricSelector is used to identify a specific time series
|
||||
// within a given metric.
|
||||
// +optional
|
||||
MetricSelector *metav1.LabelSelector
|
||||
// TargetValue is the target value of the metric (as a quantity).
|
||||
// Mutually exclusive with TargetAverageValue.
|
||||
// +optional
|
||||
TargetValue *resource.Quantity
|
||||
// TargetAverageValue is the target per-pod value of global metric (as a quantity).
|
||||
// Mutually exclusive with TargetValue.
|
||||
// +optional
|
||||
TargetAverageValue *resource.Quantity
|
||||
}
|
||||
|
||||
// HorizontalPodAutoscalerStatus describes the current status of a horizontal pod autoscaler.
|
||||
type HorizontalPodAutoscalerStatus struct {
|
||||
// ObservedGeneration is the most recent generation observed by this autoscaler.
|
||||
|
|
@ -282,6 +315,13 @@ type MetricStatus struct {
|
|||
// to normal per-pod metrics using the "pods" source.
|
||||
// +optional
|
||||
Resource *ResourceMetricStatus
|
||||
// External refers to a global metric that is not associated
|
||||
// with any Kubernetes object. It allows autoscaling based on information
|
||||
// coming from components running outside of cluster
|
||||
// (for example length of queue in cloud messaging service, or
|
||||
// QPS from loadbalancer running outside of cluster).
|
||||
// +optional
|
||||
External *ExternalMetricStatus
|
||||
}
|
||||
|
||||
// ObjectMetricStatus indicates the current value of a metric describing a
|
||||
|
|
@ -328,6 +368,23 @@ type ResourceMetricStatus struct {
|
|||
CurrentAverageValue resource.Quantity
|
||||
}
|
||||
|
||||
// ExternalMetricStatus indicates the current value of a global metric
|
||||
// not associated with any Kubernetes object.
|
||||
type ExternalMetricStatus struct {
|
||||
// MetricName is the name of a metric used for autoscaling in
|
||||
// metric system.
|
||||
MetricName string
|
||||
// MetricSelector is used to identify a specific time series
|
||||
// within a given metric.
|
||||
// +optional
|
||||
MetricSelector *metav1.LabelSelector
|
||||
// CurrentValue is the current value of the metric (as a quantity)
|
||||
CurrentValue resource.Quantity
|
||||
// CurrentAverageValue is the current value of metric averaged over autoscaled pods.
|
||||
// +optional
|
||||
CurrentAverageValue *resource.Quantity
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
|
|
|
|||
115
vendor/k8s.io/kubernetes/pkg/apis/autoscaling/zz_generated.deepcopy.go
generated
vendored
115
vendor/k8s.io/kubernetes/pkg/apis/autoscaling/zz_generated.deepcopy.go
generated
vendored
|
|
@ -16,12 +16,11 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package autoscaling
|
||||
|
||||
import (
|
||||
resource "k8s.io/apimachinery/pkg/api/resource"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
|
@ -42,6 +41,84 @@ func (in *CrossVersionObjectReference) DeepCopy() *CrossVersionObjectReference {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExternalMetricSource) DeepCopyInto(out *ExternalMetricSource) {
|
||||
*out = *in
|
||||
if in.MetricSelector != nil {
|
||||
in, out := &in.MetricSelector, &out.MetricSelector
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(v1.LabelSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
if in.TargetValue != nil {
|
||||
in, out := &in.TargetValue, &out.TargetValue
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
}
|
||||
if in.TargetAverageValue != nil {
|
||||
in, out := &in.TargetAverageValue, &out.TargetAverageValue
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalMetricSource.
|
||||
func (in *ExternalMetricSource) DeepCopy() *ExternalMetricSource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExternalMetricSource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExternalMetricStatus) DeepCopyInto(out *ExternalMetricStatus) {
|
||||
*out = *in
|
||||
if in.MetricSelector != nil {
|
||||
in, out := &in.MetricSelector, &out.MetricSelector
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(v1.LabelSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
out.CurrentValue = in.CurrentValue.DeepCopy()
|
||||
if in.CurrentAverageValue != nil {
|
||||
in, out := &in.CurrentAverageValue, &out.CurrentAverageValue
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalMetricStatus.
|
||||
func (in *ExternalMetricStatus) DeepCopy() *ExternalMetricStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExternalMetricStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HorizontalPodAutoscaler) DeepCopyInto(out *HorizontalPodAutoscaler) {
|
||||
*out = *in
|
||||
|
|
@ -66,9 +143,8 @@ func (in *HorizontalPodAutoscaler) DeepCopy() *HorizontalPodAutoscaler {
|
|||
func (in *HorizontalPodAutoscaler) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -117,9 +193,8 @@ func (in *HorizontalPodAutoscalerList) DeepCopy() *HorizontalPodAutoscalerList {
|
|||
func (in *HorizontalPodAutoscalerList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -172,8 +247,7 @@ func (in *HorizontalPodAutoscalerStatus) DeepCopyInto(out *HorizontalPodAutoscal
|
|||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(v1.Time)
|
||||
(*in).DeepCopyInto(*out)
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.CurrentMetrics != nil {
|
||||
|
|
@ -233,6 +307,15 @@ func (in *MetricSpec) DeepCopyInto(out *MetricSpec) {
|
|||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
if in.External != nil {
|
||||
in, out := &in.External, &out.External
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(ExternalMetricSource)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -276,6 +359,15 @@ func (in *MetricStatus) DeepCopyInto(out *MetricStatus) {
|
|||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
if in.External != nil {
|
||||
in, out := &in.External, &out.External
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(ExternalMetricStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -376,8 +468,8 @@ func (in *ResourceMetricSource) DeepCopyInto(out *ResourceMetricSource) {
|
|||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(resource.Quantity)
|
||||
**out = (*in).DeepCopy()
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
@ -443,9 +535,8 @@ func (in *Scale) DeepCopy() *Scale {
|
|||
func (in *Scale) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/apis/core/BUILD
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/BUILD
generated
vendored
|
|
@ -37,7 +37,6 @@ go_test(
|
|||
"toleration_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/apis/core",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/apis/core/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/OWNERS
generated
vendored
|
|
@ -37,7 +37,6 @@ reviewers:
|
|||
- yifan-gu
|
||||
- eparis
|
||||
- mwielgus
|
||||
- timothysc
|
||||
- soltysh
|
||||
- piosz
|
||||
- jsafrane
|
||||
|
|
|
|||
2
vendor/k8s.io/kubernetes/pkg/apis/core/helper/BUILD
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/apis/core/helper/BUILD
generated
vendored
|
|
@ -10,7 +10,6 @@ go_test(
|
|||
name = "go_default_test",
|
||||
srcs = ["helpers_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/apis/core/helper",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
|
|
@ -31,6 +30,7 @@ go_library(
|
|||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/selection:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
18
vendor/k8s.io/kubernetes/pkg/apis/core/helper/helpers.go
generated
vendored
18
vendor/k8s.io/kubernetes/pkg/apis/core/helper/helpers.go
generated
vendored
|
|
@ -28,6 +28,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/kubernetes/pkg/apis/core"
|
||||
)
|
||||
|
||||
|
|
@ -146,10 +147,21 @@ func IsStandardContainerResourceName(str string) bool {
|
|||
return standardContainerResources.Has(str) || IsHugePageResourceName(core.ResourceName(str))
|
||||
}
|
||||
|
||||
// IsExtendedResourceName returns true if the resource name is not in the
|
||||
// default namespace.
|
||||
// IsExtendedResourceName returns true if:
|
||||
// 1. the resource name is not in the default namespace;
|
||||
// 2. resource name does not have "requests." prefix,
|
||||
// to avoid confusion with the convention in quota
|
||||
// 3. it satisfies the rules in IsQualifiedName() after converted into quota resource name
|
||||
func IsExtendedResourceName(name core.ResourceName) bool {
|
||||
return !IsDefaultNamespaceResource(name)
|
||||
if IsDefaultNamespaceResource(name) || strings.HasPrefix(string(name), core.DefaultResourceRequestsPrefix) {
|
||||
return false
|
||||
}
|
||||
// Ensure it satisfies the rules in IsQualifiedName() after converted into quota resource name
|
||||
nameForQuota := fmt.Sprintf("%s%s", core.DefaultResourceRequestsPrefix, string(name))
|
||||
if errs := validation.IsQualifiedName(string(nameForQuota)); len(errs) != 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// IsDefaultNamespaceResource returns true if the resource name is in the
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/apis/core/install/BUILD
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/install/BUILD
generated
vendored
|
|
@ -25,7 +25,6 @@ go_test(
|
|||
name = "go_default_test",
|
||||
srcs = ["install_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/apis/core/install",
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/apis/core/pods/BUILD
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/pods/BUILD
generated
vendored
|
|
@ -12,7 +12,6 @@ go_test(
|
|||
name = "go_default_test",
|
||||
srcs = ["helpers_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/apis/core/pods",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
|
|
|
|||
114
vendor/k8s.io/kubernetes/pkg/apis/core/types.go
generated
vendored
114
vendor/k8s.io/kubernetes/pkg/apis/core/types.go
generated
vendored
|
|
@ -391,7 +391,7 @@ type PersistentVolumeSource struct {
|
|||
// More info: https://releases.k8s.io/HEAD/examples/volumes/storageos/README.md
|
||||
// +optional
|
||||
StorageOS *StorageOSPersistentVolumeSource
|
||||
// CSI (Container Storage Interface) represents storage that handled by an external CSI driver
|
||||
// CSI (Container Storage Interface) represents storage that handled by an external CSI driver (Beta feature).
|
||||
// +optional
|
||||
CSI *CSIPersistentVolumeSource
|
||||
}
|
||||
|
|
@ -467,6 +467,16 @@ type PersistentVolumeSpec struct {
|
|||
// This is an alpha feature and may change in the future.
|
||||
// +optional
|
||||
VolumeMode *PersistentVolumeMode
|
||||
// NodeAffinity defines constraints that limit what nodes this volume can be accessed from.
|
||||
// This field influences the scheduling of pods that use this volume.
|
||||
// +optional
|
||||
NodeAffinity *VolumeNodeAffinity
|
||||
}
|
||||
|
||||
// VolumeNodeAffinity defines constraints that limit what nodes this volume can be accessed from.
|
||||
type VolumeNodeAffinity struct {
|
||||
// Required specifies hard node constraints that must be met.
|
||||
Required *NodeSelector
|
||||
}
|
||||
|
||||
// PersistentVolumeReclaimPolicy describes a policy for end-of-life maintenance of persistent volumes
|
||||
|
|
@ -475,6 +485,7 @@ type PersistentVolumeReclaimPolicy string
|
|||
const (
|
||||
// PersistentVolumeReclaimRecycle means the volume will be recycled back into the pool of unbound persistent volumes on release from its claim.
|
||||
// The volume plugin must support Recycling.
|
||||
// DEPRECATED: The PersistentVolumeReclaimRecycle called Recycle is being deprecated. See announcement here: https://groups.google.com/forum/#!topic/kubernetes-dev/uexugCza84I
|
||||
PersistentVolumeReclaimRecycle PersistentVolumeReclaimPolicy = "Recycle"
|
||||
// PersistentVolumeReclaimDelete means the volume will be deleted from Kubernetes on release from its claim.
|
||||
// The volume plugin must support Deletion.
|
||||
|
|
@ -576,6 +587,8 @@ type PersistentVolumeClaimConditionType string
|
|||
const (
|
||||
// An user trigger resize of pvc has been started
|
||||
PersistentVolumeClaimResizing PersistentVolumeClaimConditionType = "Resizing"
|
||||
// PersistentVolumeClaimFileSystemResizePending - controller resize is finished and a file system resize is pending on node
|
||||
PersistentVolumeClaimFileSystemResizePending PersistentVolumeClaimConditionType = "FileSystemResizePending"
|
||||
)
|
||||
|
||||
type PersistentVolumeClaimCondition struct {
|
||||
|
|
@ -1600,7 +1613,7 @@ type LocalVolumeSource struct {
|
|||
Path string
|
||||
}
|
||||
|
||||
// Represents storage that is managed by an external CSI volume driver
|
||||
// Represents storage that is managed by an external CSI volume driver (Beta feature)
|
||||
type CSIPersistentVolumeSource struct {
|
||||
// Driver is the name of the driver to use for this volume.
|
||||
// Required.
|
||||
|
|
@ -1615,6 +1628,40 @@ type CSIPersistentVolumeSource struct {
|
|||
// Defaults to false (read/write).
|
||||
// +optional
|
||||
ReadOnly bool
|
||||
|
||||
// Filesystem type to mount.
|
||||
// Must be a filesystem type supported by the host operating system.
|
||||
// Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified.
|
||||
// +optional
|
||||
FSType string
|
||||
|
||||
// Attributes of the volume to publish.
|
||||
// +optional
|
||||
VolumeAttributes map[string]string
|
||||
|
||||
// ControllerPublishSecretRef is a reference to the secret object containing
|
||||
// sensitive information to pass to the CSI driver to complete the CSI
|
||||
// ControllerPublishVolume and ControllerUnpublishVolume calls.
|
||||
// This field is optional, and may be empty if no secret is required. If the
|
||||
// secret object contains more than one secret, all secrets are passed.
|
||||
// +optional
|
||||
ControllerPublishSecretRef *SecretReference
|
||||
|
||||
// NodeStageSecretRef is a reference to the secret object containing sensitive
|
||||
// information to pass to the CSI driver to complete the CSI NodeStageVolume
|
||||
// and NodeStageVolume and NodeUnstageVolume calls.
|
||||
// This field is optional, and may be empty if no secret is required. If the
|
||||
// secret object contains more than one secret, all secrets are passed.
|
||||
// +optional
|
||||
NodeStageSecretRef *SecretReference
|
||||
|
||||
// NodePublishSecretRef is a reference to the secret object containing
|
||||
// sensitive information to pass to the CSI driver to complete the CSI
|
||||
// NodePublishVolume and NodeUnpublishVolume calls.
|
||||
// This field is optional, and may be empty if no secret is required. If the
|
||||
// secret object contains more than one secret, all secrets are passed.
|
||||
// +optional
|
||||
NodePublishSecretRef *SecretReference
|
||||
}
|
||||
|
||||
// ContainerPort represents a network port in a single container
|
||||
|
|
@ -1655,8 +1702,7 @@ type VolumeMount struct {
|
|||
// mountPropagation determines how mounts are propagated from the host
|
||||
// to container and the other way around.
|
||||
// When not set, MountPropagationHostToContainer is used.
|
||||
// This field is alpha in 1.8 and can be reworked or removed in a future
|
||||
// release.
|
||||
// This field is beta in 1.10.
|
||||
// +optional
|
||||
MountPropagation *MountPropagationMode
|
||||
}
|
||||
|
|
@ -2568,9 +2614,10 @@ type PodSpec struct {
|
|||
// file if specified. This is only valid for non-hostNetwork pods.
|
||||
// +optional
|
||||
HostAliases []HostAlias
|
||||
// If specified, indicates the pod's priority. "SYSTEM" is a special keyword
|
||||
// which indicates the highest priority. Any other name must be defined by
|
||||
// creating a PriorityClass object with that name.
|
||||
// If specified, indicates the pod's priority. "system-node-critical" and
|
||||
// "system-cluster-critical" are two special keywords which indicate the
|
||||
// highest priorities with the former being the highest priority. Any other
|
||||
// name must be defined by creating a PriorityClass object with that name.
|
||||
// If not specified, the pod priority will be default or zero if there is no
|
||||
// default.
|
||||
// +optional
|
||||
|
|
@ -2624,6 +2671,15 @@ type PodSecurityContext struct {
|
|||
// +k8s:conversion-gen=false
|
||||
// +optional
|
||||
HostIPC bool
|
||||
// Share a single process namespace between all of the containers in a pod.
|
||||
// When this is set containers will be able to view and signal processes from other containers
|
||||
// in the same pod, and the first process in each container will not be assigned PID 1.
|
||||
// HostPID and ShareProcessNamespace cannot both be set.
|
||||
// Optional: Default to false.
|
||||
// This field is alpha-level and is honored only by servers that enable the PodShareProcessNamespace feature.
|
||||
// +k8s:conversion-gen=false
|
||||
// +optional
|
||||
ShareProcessNamespace *bool
|
||||
// The SELinux context to be applied to all containers.
|
||||
// If unspecified, the container runtime will allocate a random SELinux context for each
|
||||
// container. May also be set in SecurityContext. If set in
|
||||
|
|
@ -2638,12 +2694,20 @@ type PodSecurityContext struct {
|
|||
// for that container.
|
||||
// +optional
|
||||
RunAsUser *int64
|
||||
// The GID to run the entrypoint of the container process.
|
||||
// Uses runtime default if unset.
|
||||
// May also be set in SecurityContext. If set in both SecurityContext and
|
||||
// PodSecurityContext, the value specified in SecurityContext takes precedence
|
||||
// for that container.
|
||||
// +optional
|
||||
RunAsGroup *int64
|
||||
// Indicates that the container must run as a non-root user.
|
||||
// If true, the Kubelet will validate the image at runtime to ensure that it
|
||||
// does not run as UID 0 (root) and fail to start the container if it does.
|
||||
// If unset or false, no such validation will be performed.
|
||||
// May also be set in SecurityContext. If set in both SecurityContext and
|
||||
// PodSecurityContext, the value specified in SecurityContext takes precedence.
|
||||
// PodSecurityContext, the value specified in SecurityContext takes precedence
|
||||
// for that container.
|
||||
// +optional
|
||||
RunAsNonRoot *bool
|
||||
// A list of groups applied to the first process run in each container, in addition
|
||||
|
|
@ -2718,6 +2782,13 @@ type PodStatus struct {
|
|||
// A brief CamelCase message indicating details about why the pod is in this state. e.g. 'Evicted'
|
||||
// +optional
|
||||
Reason string
|
||||
// nominatedNodeName is set when this pod preempts other pods on the node, but it cannot be
|
||||
// scheduled right away as preemption victims receive their graceful termination periods.
|
||||
// This field does not guarantee that the pod will be scheduled on this node. Scheduler may decide
|
||||
// to place the pod elsewhere if other nodes become available sooner. Scheduler may also decide to
|
||||
// give the resources on this node to a higher priority pod that is created after preemption.
|
||||
// +optional
|
||||
NominatedNodeName string
|
||||
|
||||
// +optional
|
||||
HostIP string
|
||||
|
|
@ -3516,8 +3587,8 @@ const (
|
|||
NodeDiskPressure NodeConditionType = "DiskPressure"
|
||||
// NodeNetworkUnavailable means that network for the node is not correctly configured.
|
||||
NodeNetworkUnavailable NodeConditionType = "NetworkUnavailable"
|
||||
// NodeConfigOK indicates whether the kubelet is correctly configured
|
||||
NodeConfigOK NodeConditionType = "ConfigOK"
|
||||
// NodeKubeletConfigOk indicates whether the kubelet is correctly configured
|
||||
NodeKubeletConfigOk NodeConditionType = "KubeletConfigOk"
|
||||
)
|
||||
|
||||
type NodeCondition struct {
|
||||
|
|
@ -4048,7 +4119,7 @@ type Event struct {
|
|||
type EventSeries struct {
|
||||
// Number of occurrences in this series up to the last heartbeat time
|
||||
Count int32
|
||||
// Time of the last occurence observed
|
||||
// Time of the last occurrence observed
|
||||
LastObservedTime metav1.MicroTime
|
||||
// State of this Series: Ongoing or Finished
|
||||
State EventSeriesState
|
||||
|
|
@ -4185,6 +4256,8 @@ const (
|
|||
// HugePages request, in bytes. (500Gi = 500GiB = 500 * 1024 * 1024 * 1024)
|
||||
// As burst is not supported for HugePages, we would only quota its request, and ignore the limit.
|
||||
ResourceRequestsHugePagesPrefix = "requests.hugepages-"
|
||||
// Default resource requests prefix
|
||||
DefaultResourceRequestsPrefix = "requests."
|
||||
)
|
||||
|
||||
// A ResourceQuotaScope defines a filter that must match each object tracked by a quota
|
||||
|
|
@ -4383,8 +4456,21 @@ type ConfigMap struct {
|
|||
|
||||
// Data contains the configuration data.
|
||||
// Each key must consist of alphanumeric characters, '-', '_' or '.'.
|
||||
// Values with non-UTF-8 byte sequences must use the BinaryData field.
|
||||
// The keys stored in Data must not overlap with the keys in
|
||||
// the BinaryData field, this is enforced during validation process.
|
||||
// +optional
|
||||
Data map[string]string
|
||||
|
||||
// BinaryData contains the binary data.
|
||||
// Each key must consist of alphanumeric characters, '-', '_' or '.'.
|
||||
// BinaryData can contain byte sequences that are not in the UTF-8 range.
|
||||
// The keys stored in BinaryData must not overlap with the ones in
|
||||
// the Data field, this is enforced during validation process.
|
||||
// Using this field will require 1.10+ apiserver and
|
||||
// kubelet.
|
||||
// +optional
|
||||
BinaryData map[string][]byte
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
|
@ -4506,6 +4592,12 @@ type SecurityContext struct {
|
|||
// PodSecurityContext, the value specified in SecurityContext takes precedence.
|
||||
// +optional
|
||||
RunAsUser *int64
|
||||
// The GID to run the entrypoint of the container process.
|
||||
// Uses runtime default if unset.
|
||||
// May also be set in PodSecurityContext. If set in both SecurityContext and
|
||||
// PodSecurityContext, the value specified in SecurityContext takes precedence.
|
||||
// +optional
|
||||
RunAsGroup *int64
|
||||
// Indicates that the container must run as a non-root user.
|
||||
// If true, the Kubelet will validate the image at runtime to ensure that it
|
||||
// does not run as UID 0 (root) and fail to start the container if it does.
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/apis/core/v1/BUILD
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/v1/BUILD
generated
vendored
|
|
@ -37,7 +37,6 @@ go_test(
|
|||
"conversion_test.go",
|
||||
"defaults_test.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/apis/core/v1_test",
|
||||
deps = [
|
||||
":go_default_library",
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/apis/core/v1/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/core/v1/OWNERS
generated
vendored
|
|
@ -27,7 +27,6 @@ reviewers:
|
|||
- ncdc
|
||||
- tallclair
|
||||
- eparis
|
||||
- timothysc
|
||||
- piosz
|
||||
- jsafrane
|
||||
- dims
|
||||
|
|
|
|||
76
vendor/k8s.io/kubernetes/pkg/apis/core/v1/conversion.go
generated
vendored
76
vendor/k8s.io/kubernetes/pkg/apis/core/v1/conversion.go
generated
vendored
|
|
@ -163,7 +163,8 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
|
|||
"spec.restartPolicy",
|
||||
"spec.schedulerName",
|
||||
"status.phase",
|
||||
"status.podIP":
|
||||
"status.podIP",
|
||||
"status.nominatedNodeName":
|
||||
return label, value, nil
|
||||
// This is for backwards compatibility with old v1 clients which send spec.host
|
||||
case "spec.host":
|
||||
|
|
@ -349,6 +350,10 @@ func Convert_core_PodTemplateSpec_To_v1_PodTemplateSpec(in *core.PodTemplateSpec
|
|||
return err
|
||||
}
|
||||
|
||||
// drop init container annotations so they don't take effect on legacy kubelets.
|
||||
// remove this once the oldest supported kubelet no longer honors the annotations over the field.
|
||||
out.Annotations = dropInitContainerAnnotations(out.Annotations)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -357,6 +362,9 @@ func Convert_v1_PodTemplateSpec_To_core_PodTemplateSpec(in *v1.PodTemplateSpec,
|
|||
return err
|
||||
}
|
||||
|
||||
// drop init container annotations so they don't show up as differences when receiving requests from old clients
|
||||
out.Annotations = dropInitContainerAnnotations(out.Annotations)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -376,6 +384,7 @@ func Convert_core_PodSpec_To_v1_PodSpec(in *core.PodSpec, out *v1.PodSpec, s con
|
|||
out.HostPID = in.SecurityContext.HostPID
|
||||
out.HostNetwork = in.SecurityContext.HostNetwork
|
||||
out.HostIPC = in.SecurityContext.HostIPC
|
||||
out.ShareProcessNamespace = in.SecurityContext.ShareProcessNamespace
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -400,6 +409,18 @@ func Convert_v1_PodSpec_To_core_PodSpec(in *v1.PodSpec, out *core.PodSpec, s con
|
|||
out.SecurityContext.HostNetwork = in.HostNetwork
|
||||
out.SecurityContext.HostPID = in.HostPID
|
||||
out.SecurityContext.HostIPC = in.HostIPC
|
||||
out.SecurityContext.ShareProcessNamespace = in.ShareProcessNamespace
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_v1_Pod_To_core_Pod(in *v1.Pod, out *core.Pod, s conversion.Scope) error {
|
||||
if err := autoConvert_v1_Pod_To_core_Pod(in, out, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// drop init container annotations so they don't show up as differences when receiving requests from old clients
|
||||
out.Annotations = dropInitContainerAnnotations(out.Annotations)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -411,17 +432,7 @@ func Convert_core_Pod_To_v1_Pod(in *core.Pod, out *v1.Pod, s conversion.Scope) e
|
|||
|
||||
// drop init container annotations so they don't take effect on legacy kubelets.
|
||||
// remove this once the oldest supported kubelet no longer honors the annotations over the field.
|
||||
if len(out.Annotations) > 0 {
|
||||
old := out.Annotations
|
||||
out.Annotations = make(map[string]string, len(old))
|
||||
for k, v := range old {
|
||||
out.Annotations[k] = v
|
||||
}
|
||||
delete(out.Annotations, "pod.beta.kubernetes.io/init-containers")
|
||||
delete(out.Annotations, "pod.alpha.kubernetes.io/init-containers")
|
||||
delete(out.Annotations, "pod.beta.kubernetes.io/init-container-statuses")
|
||||
delete(out.Annotations, "pod.alpha.kubernetes.io/init-container-statuses")
|
||||
}
|
||||
out.Annotations = dropInitContainerAnnotations(out.Annotations)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -443,6 +454,7 @@ func Convert_v1_Secret_To_core_Secret(in *v1.Secret, out *core.Secret, s convers
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Convert_core_SecurityContext_To_v1_SecurityContext(in *core.SecurityContext, out *v1.SecurityContext, s conversion.Scope) error {
|
||||
if in.Capabilities != nil {
|
||||
out.Capabilities = new(v1.Capabilities)
|
||||
|
|
@ -462,6 +474,7 @@ func Convert_core_SecurityContext_To_v1_SecurityContext(in *core.SecurityContext
|
|||
out.SELinuxOptions = nil
|
||||
}
|
||||
out.RunAsUser = in.RunAsUser
|
||||
out.RunAsGroup = in.RunAsGroup
|
||||
out.RunAsNonRoot = in.RunAsNonRoot
|
||||
out.ReadOnlyRootFilesystem = in.ReadOnlyRootFilesystem
|
||||
out.AllowPrivilegeEscalation = in.AllowPrivilegeEscalation
|
||||
|
|
@ -479,6 +492,7 @@ func Convert_core_PodSecurityContext_To_v1_PodSecurityContext(in *core.PodSecuri
|
|||
out.SELinuxOptions = nil
|
||||
}
|
||||
out.RunAsUser = in.RunAsUser
|
||||
out.RunAsGroup = in.RunAsGroup
|
||||
out.RunAsNonRoot = in.RunAsNonRoot
|
||||
out.FSGroup = in.FSGroup
|
||||
return nil
|
||||
|
|
@ -495,6 +509,7 @@ func Convert_v1_PodSecurityContext_To_core_PodSecurityContext(in *v1.PodSecurity
|
|||
out.SELinuxOptions = nil
|
||||
}
|
||||
out.RunAsUser = in.RunAsUser
|
||||
out.RunAsGroup = in.RunAsGroup
|
||||
out.RunAsNonRoot = in.RunAsNonRoot
|
||||
out.FSGroup = in.FSGroup
|
||||
return nil
|
||||
|
|
@ -569,3 +584,40 @@ func AddFieldLabelConversionsForSecret(scheme *runtime.Scheme) error {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
var initContainerAnnotations = map[string]bool{
|
||||
"pod.beta.kubernetes.io/init-containers": true,
|
||||
"pod.alpha.kubernetes.io/init-containers": true,
|
||||
"pod.beta.kubernetes.io/init-container-statuses": true,
|
||||
"pod.alpha.kubernetes.io/init-container-statuses": true,
|
||||
}
|
||||
|
||||
// dropInitContainerAnnotations returns a copy of the annotations with init container annotations removed,
|
||||
// or the original annotations if no init container annotations were present.
|
||||
//
|
||||
// this can be removed once no clients prior to 1.8 are supported, and no kubelets prior to 1.8 can be run
|
||||
// (we don't support kubelets older than 2 versions skewed from the apiserver, but we don't prevent them, either)
|
||||
func dropInitContainerAnnotations(oldAnnotations map[string]string) map[string]string {
|
||||
if len(oldAnnotations) == 0 {
|
||||
return oldAnnotations
|
||||
}
|
||||
|
||||
found := false
|
||||
for k := range initContainerAnnotations {
|
||||
if _, ok := oldAnnotations[k]; ok {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return oldAnnotations
|
||||
}
|
||||
|
||||
newAnnotations := make(map[string]string, len(oldAnnotations))
|
||||
for k, v := range oldAnnotations {
|
||||
if !initContainerAnnotations[k] {
|
||||
newAnnotations[k] = v
|
||||
}
|
||||
}
|
||||
return newAnnotations
|
||||
}
|
||||
|
|
|
|||
13
vendor/k8s.io/kubernetes/pkg/apis/core/v1/defaults_test.go
generated
vendored
13
vendor/k8s.io/kubernetes/pkg/apis/core/v1/defaults_test.go
generated
vendored
|
|
@ -29,6 +29,7 @@ import (
|
|||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
utilpointer "k8s.io/kubernetes/pkg/util/pointer"
|
||||
|
||||
// enforce that all types are installed
|
||||
_ "k8s.io/kubernetes/pkg/api/testapi"
|
||||
|
|
@ -164,12 +165,6 @@ func TestSetDefaultReplicationController(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func newInt(val int32) *int32 {
|
||||
p := new(int32)
|
||||
*p = val
|
||||
return p
|
||||
}
|
||||
|
||||
func TestSetDefaultReplicationControllerReplicas(t *testing.T) {
|
||||
tests := []struct {
|
||||
rc v1.ReplicationController
|
||||
|
|
@ -192,7 +187,7 @@ func TestSetDefaultReplicationControllerReplicas(t *testing.T) {
|
|||
{
|
||||
rc: v1.ReplicationController{
|
||||
Spec: v1.ReplicationControllerSpec{
|
||||
Replicas: newInt(0),
|
||||
Replicas: utilpointer.Int32Ptr(0),
|
||||
Template: &v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
|
|
@ -207,7 +202,7 @@ func TestSetDefaultReplicationControllerReplicas(t *testing.T) {
|
|||
{
|
||||
rc: v1.ReplicationController{
|
||||
Spec: v1.ReplicationControllerSpec{
|
||||
Replicas: newInt(3),
|
||||
Replicas: utilpointer.Int32Ptr(3),
|
||||
Template: &v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
|
|
@ -1274,7 +1269,7 @@ func TestDefaultRequestIsNotSetForReplicationController(t *testing.T) {
|
|||
}
|
||||
rc := &v1.ReplicationController{
|
||||
Spec: v1.ReplicationControllerSpec{
|
||||
Replicas: newInt(3),
|
||||
Replicas: utilpointer.Int32Ptr(3),
|
||||
Template: &v1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
|
|
|
|||
2
vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/BUILD
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/BUILD
generated
vendored
|
|
@ -10,7 +10,6 @@ go_test(
|
|||
name = "go_default_test",
|
||||
srcs = ["helpers_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/apis/core/v1/helper",
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
|
|
@ -31,6 +30,7 @@ go_library(
|
|||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/selection:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
18
vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers.go
generated
vendored
18
vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers.go
generated
vendored
|
|
@ -26,13 +26,25 @@ import (
|
|||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/selection"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/kubernetes/pkg/apis/core/helper"
|
||||
)
|
||||
|
||||
// IsExtendedResourceName returns true if the resource name is not in the
|
||||
// default namespace.
|
||||
// IsExtendedResourceName returns true if:
|
||||
// 1. the resource name is not in the default namespace;
|
||||
// 2. resource name does not have "requests." prefix,
|
||||
// to avoid confusion with the convention in quota
|
||||
// 3. it satisfies the rules in IsQualifiedName() after converted into quota resource name
|
||||
func IsExtendedResourceName(name v1.ResourceName) bool {
|
||||
return !IsDefaultNamespaceResource(name)
|
||||
if IsDefaultNamespaceResource(name) || strings.HasPrefix(string(name), v1.DefaultResourceRequestsPrefix) {
|
||||
return false
|
||||
}
|
||||
// Ensure it satisfies the rules in IsQualifiedName() after converted into quota resource name
|
||||
nameForQuota := fmt.Sprintf("%s%s", v1.DefaultResourceRequestsPrefix, string(name))
|
||||
if errs := validation.IsQualifiedName(string(nameForQuota)); len(errs) != 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// IsDefaultNamespaceResource returns true if the resource name is in the
|
||||
|
|
|
|||
3
vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers_test.go
generated
vendored
3
vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/helpers_test.go
generated
vendored
|
|
@ -56,7 +56,6 @@ func TestIsDefaultNamespaceResource(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(fmt.Sprintf("resourceName input=%s, expected value=%v", tc.resourceName, tc.expectVal), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
v := IsDefaultNamespaceResource(tc.resourceName)
|
||||
|
|
@ -97,7 +96,6 @@ func TestHugePageSizeFromResourceName(t *testing.T) {
|
|||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(fmt.Sprintf("resourceName input=%s, expected value=%v", tc.resourceName, tc.expectVal), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
v, err := HugePageSizeFromResourceName(tc.resourceName)
|
||||
|
|
@ -142,7 +140,6 @@ func TestIsOvercommitAllowed(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(fmt.Sprintf("resourceName input=%s, expected value=%v", tc.resourceName, tc.expectVal), func(t *testing.T) {
|
||||
t.Parallel()
|
||||
v := IsOvercommitAllowed(tc.resourceName)
|
||||
|
|
|
|||
51
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go
generated
vendored
51
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.conversion.go
generated
vendored
|
|
@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by conversion-gen. Do not edit it manually!
|
||||
// Code generated by conversion-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
|
||||
|
|
@ -406,6 +406,8 @@ func RegisterConversions(scheme *runtime.Scheme) error {
|
|||
Convert_core_VolumeDevice_To_v1_VolumeDevice,
|
||||
Convert_v1_VolumeMount_To_core_VolumeMount,
|
||||
Convert_core_VolumeMount_To_v1_VolumeMount,
|
||||
Convert_v1_VolumeNodeAffinity_To_core_VolumeNodeAffinity,
|
||||
Convert_core_VolumeNodeAffinity_To_v1_VolumeNodeAffinity,
|
||||
Convert_v1_VolumeProjection_To_core_VolumeProjection,
|
||||
Convert_core_VolumeProjection_To_v1_VolumeProjection,
|
||||
Convert_v1_VolumeSource_To_core_VolumeSource,
|
||||
|
|
@ -619,6 +621,11 @@ func autoConvert_v1_CSIPersistentVolumeSource_To_core_CSIPersistentVolumeSource(
|
|||
out.Driver = in.Driver
|
||||
out.VolumeHandle = in.VolumeHandle
|
||||
out.ReadOnly = in.ReadOnly
|
||||
out.FSType = in.FSType
|
||||
out.VolumeAttributes = *(*map[string]string)(unsafe.Pointer(&in.VolumeAttributes))
|
||||
out.ControllerPublishSecretRef = (*core.SecretReference)(unsafe.Pointer(in.ControllerPublishSecretRef))
|
||||
out.NodeStageSecretRef = (*core.SecretReference)(unsafe.Pointer(in.NodeStageSecretRef))
|
||||
out.NodePublishSecretRef = (*core.SecretReference)(unsafe.Pointer(in.NodePublishSecretRef))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -631,6 +638,11 @@ func autoConvert_core_CSIPersistentVolumeSource_To_v1_CSIPersistentVolumeSource(
|
|||
out.Driver = in.Driver
|
||||
out.VolumeHandle = in.VolumeHandle
|
||||
out.ReadOnly = in.ReadOnly
|
||||
out.FSType = in.FSType
|
||||
out.VolumeAttributes = *(*map[string]string)(unsafe.Pointer(&in.VolumeAttributes))
|
||||
out.ControllerPublishSecretRef = (*v1.SecretReference)(unsafe.Pointer(in.ControllerPublishSecretRef))
|
||||
out.NodeStageSecretRef = (*v1.SecretReference)(unsafe.Pointer(in.NodeStageSecretRef))
|
||||
out.NodePublishSecretRef = (*v1.SecretReference)(unsafe.Pointer(in.NodePublishSecretRef))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -838,6 +850,7 @@ func Convert_core_ComponentStatusList_To_v1_ComponentStatusList(in *core.Compone
|
|||
func autoConvert_v1_ConfigMap_To_core_ConfigMap(in *v1.ConfigMap, out *core.ConfigMap, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
out.Data = *(*map[string]string)(unsafe.Pointer(&in.Data))
|
||||
out.BinaryData = *(*map[string][]byte)(unsafe.Pointer(&in.BinaryData))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -849,6 +862,7 @@ func Convert_v1_ConfigMap_To_core_ConfigMap(in *v1.ConfigMap, out *core.ConfigMa
|
|||
func autoConvert_core_ConfigMap_To_v1_ConfigMap(in *core.ConfigMap, out *v1.ConfigMap, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
out.Data = *(*map[string]string)(unsafe.Pointer(&in.Data))
|
||||
out.BinaryData = *(*map[string][]byte)(unsafe.Pointer(&in.BinaryData))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -3342,6 +3356,7 @@ func autoConvert_v1_PersistentVolumeSpec_To_core_PersistentVolumeSpec(in *v1.Per
|
|||
out.StorageClassName = in.StorageClassName
|
||||
out.MountOptions = *(*[]string)(unsafe.Pointer(&in.MountOptions))
|
||||
out.VolumeMode = (*core.PersistentVolumeMode)(unsafe.Pointer(in.VolumeMode))
|
||||
out.NodeAffinity = (*core.VolumeNodeAffinity)(unsafe.Pointer(in.NodeAffinity))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -3361,6 +3376,7 @@ func autoConvert_core_PersistentVolumeSpec_To_v1_PersistentVolumeSpec(in *core.P
|
|||
out.StorageClassName = in.StorageClassName
|
||||
out.MountOptions = *(*[]string)(unsafe.Pointer(&in.MountOptions))
|
||||
out.VolumeMode = (*v1.PersistentVolumeMode)(unsafe.Pointer(in.VolumeMode))
|
||||
out.NodeAffinity = (*v1.VolumeNodeAffinity)(unsafe.Pointer(in.NodeAffinity))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -3426,11 +3442,6 @@ func autoConvert_v1_Pod_To_core_Pod(in *v1.Pod, out *core.Pod, s conversion.Scop
|
|||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_Pod_To_core_Pod is an autogenerated conversion function.
|
||||
func Convert_v1_Pod_To_core_Pod(in *v1.Pod, out *core.Pod, s conversion.Scope) error {
|
||||
return autoConvert_v1_Pod_To_core_Pod(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_core_Pod_To_v1_Pod(in *core.Pod, out *v1.Pod, s conversion.Scope) error {
|
||||
out.ObjectMeta = in.ObjectMeta
|
||||
if err := Convert_core_PodSpec_To_v1_PodSpec(&in.Spec, &out.Spec, s); err != nil {
|
||||
|
|
@ -3763,6 +3774,7 @@ func Convert_core_PodProxyOptions_To_v1_PodProxyOptions(in *core.PodProxyOptions
|
|||
func autoConvert_v1_PodSecurityContext_To_core_PodSecurityContext(in *v1.PodSecurityContext, out *core.PodSecurityContext, s conversion.Scope) error {
|
||||
out.SELinuxOptions = (*core.SELinuxOptions)(unsafe.Pointer(in.SELinuxOptions))
|
||||
out.RunAsUser = (*int64)(unsafe.Pointer(in.RunAsUser))
|
||||
out.RunAsGroup = (*int64)(unsafe.Pointer(in.RunAsGroup))
|
||||
out.RunAsNonRoot = (*bool)(unsafe.Pointer(in.RunAsNonRoot))
|
||||
out.SupplementalGroups = *(*[]int64)(unsafe.Pointer(&in.SupplementalGroups))
|
||||
out.FSGroup = (*int64)(unsafe.Pointer(in.FSGroup))
|
||||
|
|
@ -3773,8 +3785,10 @@ func autoConvert_core_PodSecurityContext_To_v1_PodSecurityContext(in *core.PodSe
|
|||
// INFO: in.HostNetwork opted out of conversion generation
|
||||
// INFO: in.HostPID opted out of conversion generation
|
||||
// INFO: in.HostIPC opted out of conversion generation
|
||||
// INFO: in.ShareProcessNamespace opted out of conversion generation
|
||||
out.SELinuxOptions = (*v1.SELinuxOptions)(unsafe.Pointer(in.SELinuxOptions))
|
||||
out.RunAsUser = (*int64)(unsafe.Pointer(in.RunAsUser))
|
||||
out.RunAsGroup = (*int64)(unsafe.Pointer(in.RunAsGroup))
|
||||
out.RunAsNonRoot = (*bool)(unsafe.Pointer(in.RunAsNonRoot))
|
||||
out.SupplementalGroups = *(*[]int64)(unsafe.Pointer(&in.SupplementalGroups))
|
||||
out.FSGroup = (*int64)(unsafe.Pointer(in.FSGroup))
|
||||
|
|
@ -3847,6 +3861,7 @@ func autoConvert_v1_PodSpec_To_core_PodSpec(in *v1.PodSpec, out *core.PodSpec, s
|
|||
// INFO: in.HostNetwork opted out of conversion generation
|
||||
// INFO: in.HostPID opted out of conversion generation
|
||||
// INFO: in.HostIPC opted out of conversion generation
|
||||
// INFO: in.ShareProcessNamespace opted out of conversion generation
|
||||
if in.SecurityContext != nil {
|
||||
in, out := &in.SecurityContext, &out.SecurityContext
|
||||
*out = new(core.PodSecurityContext)
|
||||
|
|
@ -3938,6 +3953,7 @@ func autoConvert_v1_PodStatus_To_core_PodStatus(in *v1.PodStatus, out *core.PodS
|
|||
out.Conditions = *(*[]core.PodCondition)(unsafe.Pointer(&in.Conditions))
|
||||
out.Message = in.Message
|
||||
out.Reason = in.Reason
|
||||
out.NominatedNodeName = in.NominatedNodeName
|
||||
out.HostIP = in.HostIP
|
||||
out.PodIP = in.PodIP
|
||||
out.StartTime = (*meta_v1.Time)(unsafe.Pointer(in.StartTime))
|
||||
|
|
@ -3957,6 +3973,7 @@ func autoConvert_core_PodStatus_To_v1_PodStatus(in *core.PodStatus, out *v1.PodS
|
|||
out.Conditions = *(*[]v1.PodCondition)(unsafe.Pointer(&in.Conditions))
|
||||
out.Message = in.Message
|
||||
out.Reason = in.Reason
|
||||
out.NominatedNodeName = in.NominatedNodeName
|
||||
out.HostIP = in.HostIP
|
||||
out.PodIP = in.PodIP
|
||||
out.StartTime = (*meta_v1.Time)(unsafe.Pointer(in.StartTime))
|
||||
|
|
@ -4968,6 +4985,7 @@ func autoConvert_v1_SecurityContext_To_core_SecurityContext(in *v1.SecurityConte
|
|||
out.Privileged = (*bool)(unsafe.Pointer(in.Privileged))
|
||||
out.SELinuxOptions = (*core.SELinuxOptions)(unsafe.Pointer(in.SELinuxOptions))
|
||||
out.RunAsUser = (*int64)(unsafe.Pointer(in.RunAsUser))
|
||||
out.RunAsGroup = (*int64)(unsafe.Pointer(in.RunAsGroup))
|
||||
out.RunAsNonRoot = (*bool)(unsafe.Pointer(in.RunAsNonRoot))
|
||||
out.ReadOnlyRootFilesystem = (*bool)(unsafe.Pointer(in.ReadOnlyRootFilesystem))
|
||||
out.AllowPrivilegeEscalation = (*bool)(unsafe.Pointer(in.AllowPrivilegeEscalation))
|
||||
|
|
@ -4984,6 +5002,7 @@ func autoConvert_core_SecurityContext_To_v1_SecurityContext(in *core.SecurityCon
|
|||
out.Privileged = (*bool)(unsafe.Pointer(in.Privileged))
|
||||
out.SELinuxOptions = (*v1.SELinuxOptions)(unsafe.Pointer(in.SELinuxOptions))
|
||||
out.RunAsUser = (*int64)(unsafe.Pointer(in.RunAsUser))
|
||||
out.RunAsGroup = (*int64)(unsafe.Pointer(in.RunAsGroup))
|
||||
out.RunAsNonRoot = (*bool)(unsafe.Pointer(in.RunAsNonRoot))
|
||||
out.ReadOnlyRootFilesystem = (*bool)(unsafe.Pointer(in.ReadOnlyRootFilesystem))
|
||||
out.AllowPrivilegeEscalation = (*bool)(unsafe.Pointer(in.AllowPrivilegeEscalation))
|
||||
|
|
@ -5502,6 +5521,26 @@ func Convert_core_VolumeMount_To_v1_VolumeMount(in *core.VolumeMount, out *v1.Vo
|
|||
return autoConvert_core_VolumeMount_To_v1_VolumeMount(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_VolumeNodeAffinity_To_core_VolumeNodeAffinity(in *v1.VolumeNodeAffinity, out *core.VolumeNodeAffinity, s conversion.Scope) error {
|
||||
out.Required = (*core.NodeSelector)(unsafe.Pointer(in.Required))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_v1_VolumeNodeAffinity_To_core_VolumeNodeAffinity is an autogenerated conversion function.
|
||||
func Convert_v1_VolumeNodeAffinity_To_core_VolumeNodeAffinity(in *v1.VolumeNodeAffinity, out *core.VolumeNodeAffinity, s conversion.Scope) error {
|
||||
return autoConvert_v1_VolumeNodeAffinity_To_core_VolumeNodeAffinity(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_core_VolumeNodeAffinity_To_v1_VolumeNodeAffinity(in *core.VolumeNodeAffinity, out *v1.VolumeNodeAffinity, s conversion.Scope) error {
|
||||
out.Required = (*v1.NodeSelector)(unsafe.Pointer(in.Required))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Convert_core_VolumeNodeAffinity_To_v1_VolumeNodeAffinity is an autogenerated conversion function.
|
||||
func Convert_core_VolumeNodeAffinity_To_v1_VolumeNodeAffinity(in *core.VolumeNodeAffinity, out *v1.VolumeNodeAffinity, s conversion.Scope) error {
|
||||
return autoConvert_core_VolumeNodeAffinity_To_v1_VolumeNodeAffinity(in, out, s)
|
||||
}
|
||||
|
||||
func autoConvert_v1_VolumeProjection_To_core_VolumeProjection(in *v1.VolumeProjection, out *core.VolumeProjection, s conversion.Scope) error {
|
||||
out.Secret = (*core.SecretProjection)(unsafe.Pointer(in.Secret))
|
||||
out.DownwardAPI = (*core.DownwardAPIProjection)(unsafe.Pointer(in.DownwardAPI))
|
||||
|
|
|
|||
2
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.defaults.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/apis/core/v1/zz_generated.defaults.go
generated
vendored
|
|
@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by defaulter-gen. Do not edit it manually!
|
||||
// Code generated by defaulter-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
|
||||
|
|
|
|||
3
vendor/k8s.io/kubernetes/pkg/apis/core/validation/BUILD
generated
vendored
3
vendor/k8s.io/kubernetes/pkg/apis/core/validation/BUILD
generated
vendored
|
|
@ -52,13 +52,13 @@ go_test(
|
|||
"validation_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/apis/core/validation",
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/core/helper:go_default_library",
|
||||
"//pkg/capabilities:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/security/apparmor:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
|
|
@ -67,6 +67,7 @@ go_test(
|
|||
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
246
vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go
generated
vendored
246
vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation.go
generated
vendored
|
|
@ -64,6 +64,8 @@ const isInvalidQuotaResource string = `must be a standard resource for quota`
|
|||
const fieldImmutableErrorMsg string = apimachineryvalidation.FieldImmutableErrorMsg
|
||||
const isNotIntegerErrorMsg string = `must be an integer`
|
||||
const isNotPositiveErrorMsg string = `must be greater than zero`
|
||||
const csiDriverNameRexpErrMsg string = "must consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character"
|
||||
const csiDriverNameRexpFmt string = `^[a-zA-Z0-9][-a-zA-Z0-9_.]{0,61}[a-zA-Z-0-9]$`
|
||||
|
||||
var pdPartitionErrorMsg string = validation.InclusiveRangeError(1, 255)
|
||||
var fileModeErrorMsg string = "must be a number between 0 and 0777 (octal), both inclusive"
|
||||
|
|
@ -75,6 +77,8 @@ var iscsiInitiatorIqnRegex = regexp.MustCompile(`iqn\.\d{4}-\d{2}\.([[:alnum:]-.
|
|||
var iscsiInitiatorEuiRegex = regexp.MustCompile(`^eui.[[:alnum:]]{16}$`)
|
||||
var iscsiInitiatorNaaRegex = regexp.MustCompile(`^naa.[[:alnum:]]{32}$`)
|
||||
|
||||
var csiDriverNameRexp = regexp.MustCompile(csiDriverNameRexpFmt)
|
||||
|
||||
// ValidateHasLabel requires that metav1.ObjectMeta has a Label with key and expectedValue
|
||||
func ValidateHasLabel(meta metav1.ObjectMeta, fldPath *field.Path, key, expectedValue string) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
|
@ -202,10 +206,6 @@ func ValidateEndpointsSpecificAnnotations(annotations map[string]string, fldPath
|
|||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateOwnerReferences(ownerReferences []metav1.OwnerReference, fldPath *field.Path) field.ErrorList {
|
||||
return apimachineryvalidation.ValidateOwnerReferences(ownerReferences, fldPath)
|
||||
}
|
||||
|
||||
// ValidateNameFunc validates that the provided name is valid for a given resource type.
|
||||
// Not all resources have the same validation rules for names. Prefix is true
|
||||
// if the name will have a value appended to it. If the name is not valid,
|
||||
|
|
@ -283,11 +283,6 @@ func NameIsDNSSubdomain(name string, prefix bool) []string {
|
|||
return apimachineryvalidation.NameIsDNSSubdomain(name, prefix)
|
||||
}
|
||||
|
||||
// NameIsDNSLabel is a ValidateNameFunc for names that must be a DNS 1123 label.
|
||||
func NameIsDNSLabel(name string, prefix bool) []string {
|
||||
return apimachineryvalidation.NameIsDNSLabel(name, prefix)
|
||||
}
|
||||
|
||||
// NameIsDNS1035Label is a ValidateNameFunc for names that must be a DNS 952 label.
|
||||
func NameIsDNS1035Label(name string, prefix bool) []string {
|
||||
return apimachineryvalidation.NameIsDNS1035Label(name, prefix)
|
||||
|
|
@ -353,10 +348,6 @@ func ValidateObjectMetaUpdate(newMeta, oldMeta *metav1.ObjectMeta, fldPath *fiel
|
|||
return allErrs
|
||||
}
|
||||
|
||||
func ValidateNoNewFinalizers(newFinalizers []string, oldFinalizers []string, fldPath *field.Path) field.ErrorList {
|
||||
return apimachineryvalidation.ValidateNoNewFinalizers(newFinalizers, oldFinalizers, fldPath)
|
||||
}
|
||||
|
||||
func ValidateVolumes(volumes []core.Volume, fldPath *field.Path) (map[string]core.VolumeSource, field.ErrorList) {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
|
|
@ -1392,6 +1383,9 @@ func validateLocalVolumeSource(ls *core.LocalVolumeSource, fldPath *field.Path)
|
|||
return allErrs
|
||||
}
|
||||
|
||||
if !path.IsAbs(ls.Path) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath, ls.Path, "must be an absolute path"))
|
||||
}
|
||||
allErrs = append(allErrs, validatePathNoBacksteps(ls.Path, fldPath.Child("path"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
|
@ -1446,10 +1440,57 @@ func validateCSIPersistentVolumeSource(csi *core.CSIPersistentVolumeSource, fldP
|
|||
allErrs = append(allErrs, field.Required(fldPath.Child("driver"), ""))
|
||||
}
|
||||
|
||||
if len(csi.Driver) > 63 {
|
||||
allErrs = append(allErrs, field.TooLong(fldPath.Child("driver"), csi.Driver, 63))
|
||||
}
|
||||
|
||||
if !csiDriverNameRexp.MatchString(csi.Driver) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("driver"), csi.Driver, validation.RegexError(csiDriverNameRexpErrMsg, csiDriverNameRexpFmt, "csi-hostpath")))
|
||||
}
|
||||
|
||||
if len(csi.VolumeHandle) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("volumeHandle"), ""))
|
||||
}
|
||||
|
||||
if csi.ControllerPublishSecretRef != nil {
|
||||
if len(csi.ControllerPublishSecretRef.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("controllerPublishSecretRef", "name"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.ControllerPublishSecretRef.Name, fldPath.Child("name"))...)
|
||||
}
|
||||
if len(csi.ControllerPublishSecretRef.Namespace) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("controllerPublishSecretRef", "namespace"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.ControllerPublishSecretRef.Namespace, fldPath.Child("namespace"))...)
|
||||
}
|
||||
}
|
||||
|
||||
if csi.NodePublishSecretRef != nil {
|
||||
if len(csi.NodePublishSecretRef.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("nodePublishSecretRef ", "name"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.NodePublishSecretRef.Name, fldPath.Child("name"))...)
|
||||
}
|
||||
if len(csi.NodePublishSecretRef.Namespace) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("nodePublishSecretRef ", "namespace"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.NodePublishSecretRef.Namespace, fldPath.Child("namespace"))...)
|
||||
}
|
||||
}
|
||||
|
||||
if csi.NodeStageSecretRef != nil {
|
||||
if len(csi.NodeStageSecretRef.Name) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("nodeStageSecretRef", "name"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.NodeStageSecretRef.Name, fldPath.Child("name"))...)
|
||||
}
|
||||
if len(csi.NodeStageSecretRef.Namespace) == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("nodeStageSecretRef", "namespace"), ""))
|
||||
} else {
|
||||
allErrs = append(allErrs, ValidateDNS1123Label(csi.NodeStageSecretRef.Namespace, fldPath.Child("namespace"))...)
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
|
|
@ -1498,6 +1539,15 @@ func ValidatePersistentVolume(pv *core.PersistentVolume) field.ErrorList {
|
|||
nodeAffinitySpecified, errs := validateStorageNodeAffinityAnnotation(pv.ObjectMeta.Annotations, metaPath.Child("annotations"))
|
||||
allErrs = append(allErrs, errs...)
|
||||
|
||||
volumeNodeAffinitySpecified, errs := validateVolumeNodeAffinity(pv.Spec.NodeAffinity, specPath.Child("nodeAffinity"))
|
||||
allErrs = append(allErrs, errs...)
|
||||
|
||||
if nodeAffinitySpecified && volumeNodeAffinitySpecified {
|
||||
allErrs = append(allErrs, field.Forbidden(specPath.Child("nodeAffinity"), "may not specify both alpha nodeAffinity annotation and nodeAffinity field"))
|
||||
}
|
||||
|
||||
nodeAffinitySpecified = nodeAffinitySpecified || volumeNodeAffinitySpecified
|
||||
|
||||
numVolumes := 0
|
||||
if pv.Spec.HostPath != nil {
|
||||
if numVolumes > 0 {
|
||||
|
|
@ -1726,6 +1776,13 @@ func ValidatePersistentVolumeUpdate(newPv, oldPv *core.PersistentVolume) field.E
|
|||
allErrs = append(allErrs, ValidateImmutableField(newPv.Spec.VolumeMode, oldPv.Spec.VolumeMode, field.NewPath("volumeMode"))...)
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
|
||||
// Allow setting NodeAffinity if oldPv NodeAffinity was not set
|
||||
if oldPv.Spec.NodeAffinity != nil {
|
||||
allErrs = append(allErrs, ValidateImmutableField(newPv.Spec.NodeAffinity, oldPv.Spec.NodeAffinity, field.NewPath("nodeAffinity"))...)
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
|
|
@ -1796,6 +1853,16 @@ func ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc *core.PersistentVolumeCl
|
|||
oldPvcClone.Spec.VolumeName = newPvcClone.Spec.VolumeName
|
||||
}
|
||||
|
||||
if validateStorageClassUpgrade(oldPvcClone.Annotations, newPvcClone.Annotations,
|
||||
oldPvcClone.Spec.StorageClassName, newPvcClone.Spec.StorageClassName) {
|
||||
newPvcClone.Spec.StorageClassName = nil
|
||||
metav1.SetMetaDataAnnotation(&newPvcClone.ObjectMeta, core.BetaStorageClassAnnotation, oldPvcClone.Annotations[core.BetaStorageClassAnnotation])
|
||||
} else {
|
||||
// storageclass annotation should be immutable after creation
|
||||
// TODO: remove Beta when no longer needed
|
||||
allErrs = append(allErrs, ValidateImmutableAnnotation(newPvc.ObjectMeta.Annotations[v1.BetaStorageClassAnnotation], oldPvc.ObjectMeta.Annotations[v1.BetaStorageClassAnnotation], v1.BetaStorageClassAnnotation, field.NewPath("metadata"))...)
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.ExpandPersistentVolumes) {
|
||||
// lets make sure storage values are same.
|
||||
if newPvc.Status.Phase == core.ClaimBound && newPvcClone.Spec.Resources.Requests != nil {
|
||||
|
|
@ -1820,16 +1887,28 @@ func ValidatePersistentVolumeClaimUpdate(newPvc, oldPvc *core.PersistentVolumeCl
|
|||
}
|
||||
}
|
||||
|
||||
// storageclass annotation should be immutable after creation
|
||||
// TODO: remove Beta when no longer needed
|
||||
allErrs = append(allErrs, ValidateImmutableAnnotation(newPvc.ObjectMeta.Annotations[v1.BetaStorageClassAnnotation], oldPvc.ObjectMeta.Annotations[v1.BetaStorageClassAnnotation], v1.BetaStorageClassAnnotation, field.NewPath("metadata"))...)
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
|
||||
allErrs = append(allErrs, ValidateImmutableField(newPvc.Spec.VolumeMode, oldPvc.Spec.VolumeMode, field.NewPath("volumeMode"))...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// Provide an upgrade path from PVC with storage class specified in beta
|
||||
// annotation to storage class specified in attribute. We allow update of
|
||||
// StorageClassName only if following four conditions are met at the same time:
|
||||
// 1. The old pvc's StorageClassAnnotation is set
|
||||
// 2. The old pvc's StorageClassName is not set
|
||||
// 3. The new pvc's StorageClassName is set and equal to the old value in annotation
|
||||
// 4. If the new pvc's StorageClassAnnotation is set,it must be equal to the old pv/pvc's StorageClassAnnotation
|
||||
func validateStorageClassUpgrade(oldAnnotations, newAnnotations map[string]string, oldScName, newScName *string) bool {
|
||||
oldSc, oldAnnotationExist := oldAnnotations[core.BetaStorageClassAnnotation]
|
||||
newScInAnnotation, newAnnotationExist := newAnnotations[core.BetaStorageClassAnnotation]
|
||||
return oldAnnotationExist /* condition 1 */ &&
|
||||
oldScName == nil /* condition 2*/ &&
|
||||
(newScName != nil && *newScName == oldSc) /* condition 3 */ &&
|
||||
(!newAnnotationExist || newScInAnnotation == oldSc) /* condition 4 */
|
||||
}
|
||||
|
||||
// ValidatePersistentVolumeClaimStatusUpdate validates an update to status of a PersistentVolumeClaim
|
||||
func ValidatePersistentVolumeClaimStatusUpdate(newPvc, oldPvc *core.PersistentVolumeClaim) field.ErrorList {
|
||||
allErrs := ValidateObjectMetaUpdate(&newPvc.ObjectMeta, &oldPvc.ObjectMeta, field.NewPath("metadata"))
|
||||
|
|
@ -2185,7 +2264,11 @@ func ValidateVolumeMounts(mounts []core.VolumeMount, voldevices map[string]strin
|
|||
}
|
||||
|
||||
if len(mnt.SubPath) > 0 {
|
||||
allErrs = append(allErrs, validateLocalDescendingPath(mnt.SubPath, fldPath.Child("subPath"))...)
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeSubpath) {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("subPath"), "subPath is disabled by feature-gate"))
|
||||
} else {
|
||||
allErrs = append(allErrs, validateLocalDescendingPath(mnt.SubPath, fldPath.Child("subPath"))...)
|
||||
}
|
||||
}
|
||||
|
||||
if mnt.MountPropagation != nil {
|
||||
|
|
@ -2657,19 +2740,8 @@ func validateAffinity(affinity *core.Affinity, fldPath *field.Path) field.ErrorL
|
|||
allErrs := field.ErrorList{}
|
||||
|
||||
if affinity != nil {
|
||||
if na := affinity.NodeAffinity; na != nil {
|
||||
// TODO: Uncomment the next three lines once RequiredDuringSchedulingRequiredDuringExecution is implemented.
|
||||
// if na.RequiredDuringSchedulingRequiredDuringExecution != nil {
|
||||
// allErrs = append(allErrs, ValidateNodeSelector(na.RequiredDuringSchedulingRequiredDuringExecution, fldPath.Child("requiredDuringSchedulingRequiredDuringExecution"))...)
|
||||
// }
|
||||
|
||||
if na.RequiredDuringSchedulingIgnoredDuringExecution != nil {
|
||||
allErrs = append(allErrs, ValidateNodeSelector(na.RequiredDuringSchedulingIgnoredDuringExecution, fldPath.Child("requiredDuringSchedulingIgnoredDuringExecution"))...)
|
||||
}
|
||||
|
||||
if len(na.PreferredDuringSchedulingIgnoredDuringExecution) > 0 {
|
||||
allErrs = append(allErrs, ValidatePreferredSchedulingTerms(na.PreferredDuringSchedulingIgnoredDuringExecution, fldPath.Child("preferredDuringSchedulingIgnoredDuringExecution"))...)
|
||||
}
|
||||
if affinity.NodeAffinity != nil {
|
||||
allErrs = append(allErrs, validateNodeAffinity(affinity.NodeAffinity, fldPath.Child("nodeAffinity"))...)
|
||||
}
|
||||
if affinity.PodAffinity != nil {
|
||||
allErrs = append(allErrs, validatePodAffinity(affinity.PodAffinity, fldPath.Child("podAffinity"))...)
|
||||
|
|
@ -2907,19 +2979,13 @@ func ValidatePodSpec(spec *core.PodSpec, fldPath *field.Path) field.ErrorList {
|
|||
}
|
||||
|
||||
if len(spec.PriorityClassName) > 0 {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.PodPriority) {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("priorityClassName"), "Pod priority is disabled by feature-gate"))
|
||||
} else {
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.PodPriority) {
|
||||
for _, msg := range ValidatePriorityClassName(spec.PriorityClassName, false) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("priorityClassName"), spec.PriorityClassName, msg))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if spec.Priority != nil && !utilfeature.DefaultFeatureGate.Enabled(features.PodPriority) {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("priority"), "Pod priority is disabled by feature-gate"))
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
|
|
@ -3086,6 +3152,22 @@ func validatePodAntiAffinity(podAntiAffinity *core.PodAntiAffinity, fldPath *fie
|
|||
return allErrs
|
||||
}
|
||||
|
||||
// validateNodeAffinity tests that the specified nodeAffinity fields have valid data
|
||||
func validateNodeAffinity(na *core.NodeAffinity, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
// TODO: Uncomment the next three lines once RequiredDuringSchedulingRequiredDuringExecution is implemented.
|
||||
// if na.RequiredDuringSchedulingRequiredDuringExecution != nil {
|
||||
// allErrs = append(allErrs, ValidateNodeSelector(na.RequiredDuringSchedulingRequiredDuringExecution, fldPath.Child("requiredDuringSchedulingRequiredDuringExecution"))...)
|
||||
// }
|
||||
if na.RequiredDuringSchedulingIgnoredDuringExecution != nil {
|
||||
allErrs = append(allErrs, ValidateNodeSelector(na.RequiredDuringSchedulingIgnoredDuringExecution, fldPath.Child("requiredDuringSchedulingIgnoredDuringExecution"))...)
|
||||
}
|
||||
if len(na.PreferredDuringSchedulingIgnoredDuringExecution) > 0 {
|
||||
allErrs = append(allErrs, ValidatePreferredSchedulingTerms(na.PreferredDuringSchedulingIgnoredDuringExecution, fldPath.Child("preferredDuringSchedulingIgnoredDuringExecution"))...)
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// validatePodAffinity tests that the specified podAffinity fields have valid data
|
||||
func validatePodAffinity(podAffinity *core.PodAffinity, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := field.ErrorList{}
|
||||
|
|
@ -3220,11 +3302,24 @@ func ValidatePodSecurityContext(securityContext *core.PodSecurityContext, spec *
|
|||
allErrs = append(allErrs, field.Invalid(fldPath.Child("runAsUser"), *(securityContext.RunAsUser), msg))
|
||||
}
|
||||
}
|
||||
if securityContext.RunAsGroup != nil {
|
||||
for _, msg := range validation.IsValidGroupID(*securityContext.RunAsGroup) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("runAsGroup"), *(securityContext.RunAsGroup), msg))
|
||||
}
|
||||
}
|
||||
|
||||
for g, gid := range securityContext.SupplementalGroups {
|
||||
for _, msg := range validation.IsValidGroupID(gid) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("supplementalGroups").Index(g), gid, msg))
|
||||
}
|
||||
}
|
||||
if securityContext.ShareProcessNamespace != nil {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.PodShareProcessNamespace) {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("shareProcessNamespace"), "Process Namespace Sharing is disabled by PodShareProcessNamespace feature-gate"))
|
||||
} else if securityContext.HostPID && *securityContext.ShareProcessNamespace {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("shareProcessNamespace"), *securityContext.ShareProcessNamespace, "ShareProcessNamespace and HostPID cannot both be enabled"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allErrs
|
||||
|
|
@ -3369,6 +3464,12 @@ func ValidatePodStatusUpdate(newPod, oldPod *core.Pod) field.ErrorList {
|
|||
allErrs = append(allErrs, field.Forbidden(fldPath.Child("nodeName"), "may not be changed directly"))
|
||||
}
|
||||
|
||||
if newPod.Status.NominatedNodeName != oldPod.Status.NominatedNodeName && len(newPod.Status.NominatedNodeName) > 0 {
|
||||
for _, msg := range ValidateNodeName(newPod.Status.NominatedNodeName, false) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("nominatedNodeName"), newPod.Status.NominatedNodeName, msg))
|
||||
}
|
||||
}
|
||||
|
||||
// If pod should not restart, make sure the status update does not transition
|
||||
// any terminated containers to a non-terminated state.
|
||||
allErrs = append(allErrs, ValidateContainerStateTransition(newPod.Status.ContainerStatuses, oldPod.Status.ContainerStatuses, fldPath.Child("containerStatuses"), oldPod.Spec.RestartPolicy)...)
|
||||
|
|
@ -3406,7 +3507,7 @@ func ValidatePodTemplate(pod *core.PodTemplate) field.ErrorList {
|
|||
// ValidatePodTemplateUpdate tests to see if the update is legal for an end user to make. newPod is updated with fields
|
||||
// that cannot be changed.
|
||||
func ValidatePodTemplateUpdate(newPod, oldPod *core.PodTemplate) field.ErrorList {
|
||||
allErrs := ValidateObjectMetaUpdate(&oldPod.ObjectMeta, &newPod.ObjectMeta, field.NewPath("metadata"))
|
||||
allErrs := ValidateObjectMetaUpdate(&newPod.ObjectMeta, &oldPod.ObjectMeta, field.NewPath("metadata"))
|
||||
allErrs = append(allErrs, ValidatePodTemplateSpec(&newPod.Template, field.NewPath("template"))...)
|
||||
return allErrs
|
||||
}
|
||||
|
|
@ -4039,6 +4140,10 @@ func validateContainerResourceName(value string, fldPath *field.Path) field.Erro
|
|||
if !helper.IsStandardContainerResourceName(value) {
|
||||
return append(allErrs, field.Invalid(fldPath, value, "must be a standard resource for containers"))
|
||||
}
|
||||
} else if !helper.IsDefaultNamespaceResource(core.ResourceName(value)) {
|
||||
if !helper.IsExtendedResourceName(core.ResourceName(value)) {
|
||||
return append(allErrs, field.Invalid(fldPath, value, "doesn't follow extended resource name standard"))
|
||||
}
|
||||
}
|
||||
return allErrs
|
||||
}
|
||||
|
|
@ -4220,7 +4325,8 @@ func ValidateLimitRange(limitRange *core.LimitRange) field.ErrorList {
|
|||
}
|
||||
}
|
||||
|
||||
// for GPU and hugepages, the default value and defaultRequest value must match if both are specified
|
||||
// for GPU, hugepages and other resources that are not allowed to overcommit,
|
||||
// the default value and defaultRequest value must match if both are specified
|
||||
if !helper.IsOvercommitAllowed(core.ResourceName(k)) && defaultQuantityFound && defaultRequestQuantityFound && defaultQuantity.Cmp(defaultRequestQuantity) != 0 {
|
||||
allErrs = append(allErrs, field.Invalid(idxPath.Child("defaultRequest").Key(string(k)), defaultRequestQuantity, fmt.Sprintf("default value %s must equal to defaultRequest value %s in %s", defaultQuantity.String(), defaultRequestQuantity.String(), k)))
|
||||
}
|
||||
|
|
@ -4351,10 +4457,22 @@ func ValidateConfigMap(cfg *core.ConfigMap) field.ErrorList {
|
|||
for _, msg := range validation.IsConfigMapKey(key) {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("data").Key(key), key, msg))
|
||||
}
|
||||
// check if we have a duplicate key in the other bag
|
||||
if _, isValue := cfg.BinaryData[key]; isValue {
|
||||
msg := "duplicate of key present in binaryData"
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("data").Key(key), key, msg))
|
||||
}
|
||||
totalSize += len(value)
|
||||
}
|
||||
for key, value := range cfg.BinaryData {
|
||||
for _, msg := range validation.IsConfigMapKey(key) {
|
||||
allErrs = append(allErrs, field.Invalid(field.NewPath("binaryData").Key(key), key, msg))
|
||||
}
|
||||
totalSize += len(value)
|
||||
}
|
||||
if totalSize > core.MaxSecretSize {
|
||||
allErrs = append(allErrs, field.TooLong(field.NewPath("data"), "", core.MaxSecretSize))
|
||||
// pass back "" to indicate that the error refers to the whole object.
|
||||
allErrs = append(allErrs, field.TooLong(field.NewPath(""), cfg, core.MaxSecretSize))
|
||||
}
|
||||
|
||||
return allErrs
|
||||
|
|
@ -4808,8 +4926,14 @@ func ValidateSecurityContext(sc *core.SecurityContext, fldPath *field.Path) fiel
|
|||
}
|
||||
|
||||
if sc.RunAsUser != nil {
|
||||
if *sc.RunAsUser < 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("runAsUser"), *sc.RunAsUser, isNegativeErrorMsg))
|
||||
for _, msg := range validation.IsValidUserID(*sc.RunAsUser) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("runAsUser"), *sc.RunAsUser, msg))
|
||||
}
|
||||
}
|
||||
|
||||
if sc.RunAsGroup != nil {
|
||||
for _, msg := range validation.IsValidGroupID(*sc.RunAsGroup) {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("runAsGroup"), *sc.RunAsGroup, msg))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4898,7 +5022,7 @@ func validateStorageNodeAffinityAnnotation(annotations map[string]string, fldPat
|
|||
return false, allErrs
|
||||
}
|
||||
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.PersistentLocalVolumes) {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath, "Storage node affinity is disabled by feature-gate"))
|
||||
}
|
||||
|
||||
|
|
@ -4914,6 +5038,30 @@ func validateStorageNodeAffinityAnnotation(annotations map[string]string, fldPat
|
|||
return policySpecified, allErrs
|
||||
}
|
||||
|
||||
// validateVolumeNodeAffinity tests that the PersistentVolume.NodeAffinity has valid data
|
||||
// returns:
|
||||
// - true if volumeNodeAffinity is set
|
||||
// - errorList if there are validation errors
|
||||
func validateVolumeNodeAffinity(nodeAffinity *core.VolumeNodeAffinity, fldPath *field.Path) (bool, field.ErrorList) {
|
||||
allErrs := field.ErrorList{}
|
||||
|
||||
if nodeAffinity == nil {
|
||||
return false, allErrs
|
||||
}
|
||||
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
|
||||
allErrs = append(allErrs, field.Forbidden(fldPath, "Volume node affinity is disabled by feature-gate"))
|
||||
}
|
||||
|
||||
if nodeAffinity.Required != nil {
|
||||
allErrs = append(allErrs, ValidateNodeSelector(nodeAffinity.Required, fldPath.Child("required"))...)
|
||||
} else {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("required"), "must specify required node constraints"))
|
||||
}
|
||||
|
||||
return true, allErrs
|
||||
}
|
||||
|
||||
// ValidateCIDR validates whether a CIDR matches the conventions expected by net.ParseCIDR
|
||||
func ValidateCIDR(cidr string) (*net.IPNet, error) {
|
||||
_, net, err := net.ParseCIDR(cidr)
|
||||
|
|
@ -4922,3 +5070,13 @@ func ValidateCIDR(cidr string) (*net.IPNet, error) {
|
|||
}
|
||||
return net, nil
|
||||
}
|
||||
|
||||
func IsDecremented(update, old *int32) bool {
|
||||
if update == nil && old != nil {
|
||||
return true
|
||||
}
|
||||
if update == nil || old == nil {
|
||||
return false
|
||||
}
|
||||
return *update < *old
|
||||
}
|
||||
|
|
|
|||
910
vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation_test.go
generated
vendored
910
vendor/k8s.io/kubernetes/pkg/apis/core/validation/validation_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
294
vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go
generated
vendored
294
vendor/k8s.io/kubernetes/pkg/apis/core/zz_generated.deepcopy.go
generated
vendored
|
|
@ -16,12 +16,11 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
resource "k8s.io/apimachinery/pkg/api/resource"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
|
|
@ -241,14 +240,47 @@ func (in *Binding) DeepCopy() *Binding {
|
|||
func (in *Binding) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CSIPersistentVolumeSource) DeepCopyInto(out *CSIPersistentVolumeSource) {
|
||||
*out = *in
|
||||
if in.VolumeAttributes != nil {
|
||||
in, out := &in.VolumeAttributes, &out.VolumeAttributes
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.ControllerPublishSecretRef != nil {
|
||||
in, out := &in.ControllerPublishSecretRef, &out.ControllerPublishSecretRef
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(SecretReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
if in.NodeStageSecretRef != nil {
|
||||
in, out := &in.NodeStageSecretRef, &out.NodeStageSecretRef
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(SecretReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
if in.NodePublishSecretRef != nil {
|
||||
in, out := &in.NodePublishSecretRef, &out.NodePublishSecretRef
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(SecretReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -432,9 +464,8 @@ func (in *ComponentStatus) DeepCopy() *ComponentStatus {
|
|||
func (in *ComponentStatus) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -466,9 +497,8 @@ func (in *ComponentStatusList) DeepCopy() *ComponentStatusList {
|
|||
func (in *ComponentStatusList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -483,6 +513,18 @@ func (in *ConfigMap) DeepCopyInto(out *ConfigMap) {
|
|||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.BinaryData != nil {
|
||||
in, out := &in.BinaryData, &out.BinaryData
|
||||
*out = make(map[string][]byte, len(*in))
|
||||
for key, val := range *in {
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
(*out)[key] = make([]byte, len(val))
|
||||
copy((*out)[key], val)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -500,9 +542,8 @@ func (in *ConfigMap) DeepCopy() *ConfigMap {
|
|||
func (in *ConfigMap) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -586,9 +627,8 @@ func (in *ConfigMapList) DeepCopy() *ConfigMapList {
|
|||
func (in *ConfigMapList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -982,9 +1022,8 @@ func (in *DeleteOptions) DeepCopy() *DeleteOptions {
|
|||
func (in *DeleteOptions) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -1093,8 +1132,8 @@ func (in *EmptyDirVolumeSource) DeepCopyInto(out *EmptyDirVolumeSource) {
|
|||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(resource.Quantity)
|
||||
**out = (*in).DeepCopy()
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
@ -1224,9 +1263,8 @@ func (in *Endpoints) DeepCopy() *Endpoints {
|
|||
func (in *Endpoints) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -1258,9 +1296,8 @@ func (in *EndpointsList) DeepCopy() *EndpointsList {
|
|||
func (in *EndpointsList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -1419,9 +1456,8 @@ func (in *Event) DeepCopy() *Event {
|
|||
func (in *Event) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -1453,9 +1489,8 @@ func (in *EventList) DeepCopy() *EventList {
|
|||
func (in *EventList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -1962,9 +1997,8 @@ func (in *LimitRange) DeepCopy() *LimitRange {
|
|||
func (in *LimitRange) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -2047,9 +2081,8 @@ func (in *LimitRangeList) DeepCopy() *LimitRangeList {
|
|||
func (in *LimitRangeList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -2108,9 +2141,8 @@ func (in *List) DeepCopy() *List {
|
|||
func (in *List) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -2153,9 +2185,8 @@ func (in *ListOptions) DeepCopy() *ListOptions {
|
|||
func (in *ListOptions) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -2267,9 +2298,8 @@ func (in *Namespace) DeepCopy() *Namespace {
|
|||
func (in *Namespace) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -2301,9 +2331,8 @@ func (in *NamespaceList) DeepCopy() *NamespaceList {
|
|||
func (in *NamespaceList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -2367,9 +2396,8 @@ func (in *Node) DeepCopy() *Node {
|
|||
func (in *Node) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -2468,9 +2496,8 @@ func (in *NodeConfigSource) DeepCopy() *NodeConfigSource {
|
|||
func (in *NodeConfigSource) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -2519,9 +2546,8 @@ func (in *NodeList) DeepCopy() *NodeList {
|
|||
func (in *NodeList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -2545,9 +2571,8 @@ func (in *NodeProxyOptions) DeepCopy() *NodeProxyOptions {
|
|||
func (in *NodeProxyOptions) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -2774,8 +2799,7 @@ func (in *ObjectMeta) DeepCopyInto(out *ObjectMeta) {
|
|||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(v1.Time)
|
||||
(*in).DeepCopyInto(*out)
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.DeletionGracePeriodSeconds != nil {
|
||||
|
|
@ -2855,9 +2879,8 @@ func (in *ObjectReference) DeepCopy() *ObjectReference {
|
|||
func (in *ObjectReference) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -2884,9 +2907,8 @@ func (in *PersistentVolume) DeepCopy() *PersistentVolume {
|
|||
func (in *PersistentVolume) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -2913,9 +2935,8 @@ func (in *PersistentVolumeClaim) DeepCopy() *PersistentVolumeClaim {
|
|||
func (in *PersistentVolumeClaim) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -2965,9 +2986,8 @@ func (in *PersistentVolumeClaimList) DeepCopy() *PersistentVolumeClaimList {
|
|||
func (in *PersistentVolumeClaimList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -3099,9 +3119,8 @@ func (in *PersistentVolumeList) DeepCopy() *PersistentVolumeList {
|
|||
func (in *PersistentVolumeList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -3302,7 +3321,7 @@ func (in *PersistentVolumeSource) DeepCopyInto(out *PersistentVolumeSource) {
|
|||
*out = nil
|
||||
} else {
|
||||
*out = new(CSIPersistentVolumeSource)
|
||||
**out = **in
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
@ -3357,6 +3376,15 @@ func (in *PersistentVolumeSpec) DeepCopyInto(out *PersistentVolumeSpec) {
|
|||
**out = **in
|
||||
}
|
||||
}
|
||||
if in.NodeAffinity != nil {
|
||||
in, out := &in.NodeAffinity, &out.NodeAffinity
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(VolumeNodeAffinity)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -3426,9 +3454,8 @@ func (in *Pod) DeepCopy() *Pod {
|
|||
func (in *Pod) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -3542,9 +3569,8 @@ func (in *PodAttachOptions) DeepCopy() *PodAttachOptions {
|
|||
func (in *PodAttachOptions) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -3649,9 +3675,8 @@ func (in *PodExecOptions) DeepCopy() *PodExecOptions {
|
|||
func (in *PodExecOptions) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -3683,9 +3708,8 @@ func (in *PodList) DeepCopy() *PodList {
|
|||
func (in *PodList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -3706,8 +3730,7 @@ func (in *PodLogOptions) DeepCopyInto(out *PodLogOptions) {
|
|||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(v1.Time)
|
||||
(*in).DeepCopyInto(*out)
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.TailLines != nil {
|
||||
|
|
@ -3745,9 +3768,8 @@ func (in *PodLogOptions) DeepCopy() *PodLogOptions {
|
|||
func (in *PodLogOptions) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -3776,9 +3798,8 @@ func (in *PodPortForwardOptions) DeepCopy() *PodPortForwardOptions {
|
|||
func (in *PodPortForwardOptions) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -3802,14 +3823,22 @@ func (in *PodProxyOptions) DeepCopy() *PodProxyOptions {
|
|||
func (in *PodProxyOptions) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PodSecurityContext) DeepCopyInto(out *PodSecurityContext) {
|
||||
*out = *in
|
||||
if in.ShareProcessNamespace != nil {
|
||||
in, out := &in.ShareProcessNamespace, &out.ShareProcessNamespace
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
if in.SELinuxOptions != nil {
|
||||
in, out := &in.SELinuxOptions, &out.SELinuxOptions
|
||||
if *in == nil {
|
||||
|
|
@ -3828,6 +3857,15 @@ func (in *PodSecurityContext) DeepCopyInto(out *PodSecurityContext) {
|
|||
**out = **in
|
||||
}
|
||||
}
|
||||
if in.RunAsGroup != nil {
|
||||
in, out := &in.RunAsGroup, &out.RunAsGroup
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
if in.RunAsNonRoot != nil {
|
||||
in, out := &in.RunAsNonRoot, &out.RunAsNonRoot
|
||||
if *in == nil {
|
||||
|
|
@ -4030,8 +4068,7 @@ func (in *PodStatus) DeepCopyInto(out *PodStatus) {
|
|||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(v1.Time)
|
||||
(*in).DeepCopyInto(*out)
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.InitContainerStatuses != nil {
|
||||
|
|
@ -4084,9 +4121,8 @@ func (in *PodStatusResult) DeepCopy() *PodStatusResult {
|
|||
func (in *PodStatusResult) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -4112,9 +4148,8 @@ func (in *PodTemplate) DeepCopy() *PodTemplate {
|
|||
func (in *PodTemplate) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -4146,9 +4181,8 @@ func (in *PodTemplateList) DeepCopy() *PodTemplateList {
|
|||
func (in *PodTemplateList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -4397,9 +4431,8 @@ func (in *RangeAllocation) DeepCopy() *RangeAllocation {
|
|||
func (in *RangeAllocation) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -4426,9 +4459,8 @@ func (in *ReplicationController) DeepCopy() *ReplicationController {
|
|||
func (in *ReplicationController) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -4477,9 +4509,8 @@ func (in *ReplicationControllerList) DeepCopy() *ReplicationControllerList {
|
|||
func (in *ReplicationControllerList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -4554,6 +4585,28 @@ func (in *ResourceFieldSelector) DeepCopy() *ResourceFieldSelector {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in ResourceList) DeepCopyInto(out *ResourceList) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(ResourceList, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val.DeepCopy()
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceList.
|
||||
func (in ResourceList) DeepCopy() ResourceList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ResourceList)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ResourceQuota) DeepCopyInto(out *ResourceQuota) {
|
||||
*out = *in
|
||||
|
|
@ -4578,9 +4631,8 @@ func (in *ResourceQuota) DeepCopy() *ResourceQuota {
|
|||
func (in *ResourceQuota) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -4612,9 +4664,8 @@ func (in *ResourceQuotaList) DeepCopy() *ResourceQuotaList {
|
|||
func (in *ResourceQuotaList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -4805,9 +4856,8 @@ func (in *Secret) DeepCopy() *Secret {
|
|||
func (in *Secret) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -4891,9 +4941,8 @@ func (in *SecretList) DeepCopy() *SecretList {
|
|||
func (in *SecretList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -5025,6 +5074,15 @@ func (in *SecurityContext) DeepCopyInto(out *SecurityContext) {
|
|||
**out = **in
|
||||
}
|
||||
}
|
||||
if in.RunAsGroup != nil {
|
||||
in, out := &in.RunAsGroup, &out.RunAsGroup
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(int64)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
if in.RunAsNonRoot != nil {
|
||||
in, out := &in.RunAsNonRoot, &out.RunAsNonRoot
|
||||
if *in == nil {
|
||||
|
|
@ -5087,9 +5145,8 @@ func (in *SerializedReference) DeepCopy() *SerializedReference {
|
|||
func (in *SerializedReference) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -5116,9 +5173,8 @@ func (in *Service) DeepCopy() *Service {
|
|||
func (in *Service) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -5162,9 +5218,8 @@ func (in *ServiceAccount) DeepCopy() *ServiceAccount {
|
|||
func (in *ServiceAccount) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -5196,9 +5251,8 @@ func (in *ServiceAccountList) DeepCopy() *ServiceAccountList {
|
|||
func (in *ServiceAccountList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -5230,9 +5284,8 @@ func (in *ServiceList) DeepCopy() *ServiceList {
|
|||
func (in *ServiceList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -5273,9 +5326,8 @@ func (in *ServiceProxyOptions) DeepCopy() *ServiceProxyOptions {
|
|||
func (in *ServiceProxyOptions) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -5458,8 +5510,7 @@ func (in *Taint) DeepCopyInto(out *Taint) {
|
|||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(v1.Time)
|
||||
(*in).DeepCopyInto(*out)
|
||||
*out = (*in).DeepCopy()
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
@ -5558,6 +5609,31 @@ func (in *VolumeMount) DeepCopy() *VolumeMount {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VolumeNodeAffinity) DeepCopyInto(out *VolumeNodeAffinity) {
|
||||
*out = *in
|
||||
if in.Required != nil {
|
||||
in, out := &in.Required, &out.Required
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(NodeSelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeNodeAffinity.
|
||||
func (in *VolumeNodeAffinity) DeepCopy() *VolumeNodeAffinity {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(VolumeNodeAffinity)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *VolumeProjection) DeepCopyInto(out *VolumeProjection) {
|
||||
*out = *in
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/apis/extensions/BUILD
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/extensions/BUILD
generated
vendored
|
|
@ -10,7 +10,6 @@ go_test(
|
|||
name = "go_default_test",
|
||||
srcs = ["helpers_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/apis/extensions",
|
||||
)
|
||||
|
||||
go_library(
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/apis/extensions/OWNERS
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/apis/extensions/OWNERS
generated
vendored
|
|
@ -19,7 +19,6 @@ reviewers:
|
|||
- ncdc
|
||||
- tallclair
|
||||
- mwielgus
|
||||
- timothysc
|
||||
- soltysh
|
||||
- piosz
|
||||
- dims
|
||||
|
|
|
|||
38
vendor/k8s.io/kubernetes/pkg/apis/extensions/zz_generated.deepcopy.go
generated
vendored
38
vendor/k8s.io/kubernetes/pkg/apis/extensions/zz_generated.deepcopy.go
generated
vendored
|
|
@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package extensions
|
||||
|
||||
|
|
@ -162,9 +162,8 @@ func (in *DaemonSet) DeepCopy() *DaemonSet {
|
|||
func (in *DaemonSet) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -213,9 +212,8 @@ func (in *DaemonSetList) DeepCopy() *DaemonSetList {
|
|||
func (in *DaemonSetList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -335,9 +333,8 @@ func (in *Deployment) DeepCopy() *Deployment {
|
|||
func (in *Deployment) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -387,9 +384,8 @@ func (in *DeploymentList) DeepCopy() *DeploymentList {
|
|||
func (in *DeploymentList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -421,9 +417,8 @@ func (in *DeploymentRollback) DeepCopy() *DeploymentRollback {
|
|||
func (in *DeploymentRollback) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -652,9 +647,8 @@ func (in *Ingress) DeepCopy() *Ingress {
|
|||
func (in *Ingress) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -703,9 +697,8 @@ func (in *IngressList) DeepCopy() *IngressList {
|
|||
func (in *IngressList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -850,9 +843,8 @@ func (in *PodSecurityPolicy) DeepCopy() *PodSecurityPolicy {
|
|||
func (in *PodSecurityPolicy) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -884,9 +876,8 @@ func (in *PodSecurityPolicyList) DeepCopy() *PodSecurityPolicyList {
|
|||
func (in *PodSecurityPolicyList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -977,9 +968,8 @@ func (in *ReplicaSet) DeepCopy() *ReplicaSet {
|
|||
func (in *ReplicaSet) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -1028,9 +1018,8 @@ func (in *ReplicaSetList) DeepCopy() *ReplicaSetList {
|
|||
func (in *ReplicaSetList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -1103,9 +1092,8 @@ func (in *ReplicationControllerDummy) DeepCopy() *ReplicationControllerDummy {
|
|||
func (in *ReplicationControllerDummy) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
|
|||
8
vendor/k8s.io/kubernetes/pkg/apis/networking/zz_generated.deepcopy.go
generated
vendored
8
vendor/k8s.io/kubernetes/pkg/apis/networking/zz_generated.deepcopy.go
generated
vendored
|
|
@ -16,7 +16,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
// This file was autogenerated by deepcopy-gen. Do not edit it manually!
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package networking
|
||||
|
||||
|
|
@ -71,9 +71,8 @@ func (in *NetworkPolicy) DeepCopy() *NetworkPolicy {
|
|||
func (in *NetworkPolicy) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
@ -165,9 +164,8 @@ func (in *NetworkPolicyList) DeepCopy() *NetworkPolicyList {
|
|||
func (in *NetworkPolicyList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/capabilities/BUILD
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/capabilities/BUILD
generated
vendored
|
|
@ -19,7 +19,6 @@ go_test(
|
|||
name = "go_default_test",
|
||||
srcs = ["capabilities_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/capabilities",
|
||||
)
|
||||
|
||||
filegroup(
|
||||
|
|
|
|||
51
vendor/k8s.io/kubernetes/pkg/cloudprovider/cloud.go
generated
vendored
51
vendor/k8s.io/kubernetes/pkg/cloudprovider/cloud.go
generated
vendored
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package cloudprovider
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
|
@ -56,9 +57,9 @@ type InformerUser interface {
|
|||
// Clusters is an abstract, pluggable interface for clusters of containers.
|
||||
type Clusters interface {
|
||||
// ListClusters lists the names of the available clusters.
|
||||
ListClusters() ([]string, error)
|
||||
ListClusters(ctx context.Context) ([]string, error)
|
||||
// Master gets back the address (either DNS name or IP address) of the master node for the cluster.
|
||||
Master(clusterName string) (string, error)
|
||||
Master(ctx context.Context, clusterName string) (string, error)
|
||||
}
|
||||
|
||||
// TODO(#6812): Use a shorter name that's less likely to be longer than cloud
|
||||
|
|
@ -75,12 +76,12 @@ func GetLoadBalancerName(service *v1.Service) string {
|
|||
}
|
||||
|
||||
// GetInstanceProviderID builds a ProviderID for a node in a cloud.
|
||||
func GetInstanceProviderID(cloud Interface, nodeName types.NodeName) (string, error) {
|
||||
func GetInstanceProviderID(ctx context.Context, cloud Interface, nodeName types.NodeName) (string, error) {
|
||||
instances, ok := cloud.Instances()
|
||||
if !ok {
|
||||
return "", fmt.Errorf("failed to get instances from cloud provider")
|
||||
}
|
||||
instanceID, err := instances.InstanceID(nodeName)
|
||||
instanceID, err := instances.InstanceID(ctx, nodeName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get instance ID from cloud provider: %v", err)
|
||||
}
|
||||
|
|
@ -94,17 +95,17 @@ type LoadBalancer interface {
|
|||
// if so, what its status is.
|
||||
// Implementations must treat the *v1.Service parameter as read-only and not modify it.
|
||||
// Parameter 'clusterName' is the name of the cluster as presented to kube-controller-manager
|
||||
GetLoadBalancer(clusterName string, service *v1.Service) (status *v1.LoadBalancerStatus, exists bool, err error)
|
||||
GetLoadBalancer(ctx context.Context, clusterName string, service *v1.Service) (status *v1.LoadBalancerStatus, exists bool, err error)
|
||||
// EnsureLoadBalancer creates a new load balancer 'name', or updates the existing one. Returns the status of the balancer
|
||||
// Implementations must treat the *v1.Service and *v1.Node
|
||||
// parameters as read-only and not modify them.
|
||||
// Parameter 'clusterName' is the name of the cluster as presented to kube-controller-manager
|
||||
EnsureLoadBalancer(clusterName string, service *v1.Service, nodes []*v1.Node) (*v1.LoadBalancerStatus, error)
|
||||
EnsureLoadBalancer(ctx context.Context, clusterName string, service *v1.Service, nodes []*v1.Node) (*v1.LoadBalancerStatus, error)
|
||||
// UpdateLoadBalancer updates hosts under the specified load balancer.
|
||||
// Implementations must treat the *v1.Service and *v1.Node
|
||||
// parameters as read-only and not modify them.
|
||||
// Parameter 'clusterName' is the name of the cluster as presented to kube-controller-manager
|
||||
UpdateLoadBalancer(clusterName string, service *v1.Service, nodes []*v1.Node) error
|
||||
UpdateLoadBalancer(ctx context.Context, clusterName string, service *v1.Service, nodes []*v1.Node) error
|
||||
// EnsureLoadBalancerDeleted deletes the specified load balancer if it
|
||||
// exists, returning nil if the load balancer specified either didn't exist or
|
||||
// was successfully deleted.
|
||||
|
|
@ -113,7 +114,7 @@ type LoadBalancer interface {
|
|||
// doesn't exist even if some part of it is still laying around.
|
||||
// Implementations must treat the *v1.Service parameter as read-only and not modify it.
|
||||
// Parameter 'clusterName' is the name of the cluster as presented to kube-controller-manager
|
||||
EnsureLoadBalancerDeleted(clusterName string, service *v1.Service) error
|
||||
EnsureLoadBalancerDeleted(ctx context.Context, clusterName string, service *v1.Service) error
|
||||
}
|
||||
|
||||
// Instances is an abstract, pluggable interface for sets of instances.
|
||||
|
|
@ -122,31 +123,31 @@ type Instances interface {
|
|||
// TODO(roberthbailey): This currently is only used in such a way that it
|
||||
// returns the address of the calling instance. We should do a rename to
|
||||
// make this clearer.
|
||||
NodeAddresses(name types.NodeName) ([]v1.NodeAddress, error)
|
||||
NodeAddresses(ctx context.Context, name types.NodeName) ([]v1.NodeAddress, error)
|
||||
// NodeAddressesByProviderID returns the addresses of the specified instance.
|
||||
// The instance is specified using the providerID of the node. The
|
||||
// ProviderID is a unique identifier of the node. This will not be called
|
||||
// from the node whose nodeaddresses are being queried. i.e. local metadata
|
||||
// services cannot be used in this method to obtain nodeaddresses
|
||||
NodeAddressesByProviderID(providerID string) ([]v1.NodeAddress, error)
|
||||
NodeAddressesByProviderID(ctx context.Context, providerID string) ([]v1.NodeAddress, error)
|
||||
// ExternalID returns the cloud provider ID of the node with the specified NodeName.
|
||||
// Note that if the instance does not exist or is no longer running, we must return ("", cloudprovider.InstanceNotFound)
|
||||
ExternalID(nodeName types.NodeName) (string, error)
|
||||
ExternalID(ctx context.Context, nodeName types.NodeName) (string, error)
|
||||
// InstanceID returns the cloud provider ID of the node with the specified NodeName.
|
||||
InstanceID(nodeName types.NodeName) (string, error)
|
||||
InstanceID(ctx context.Context, nodeName types.NodeName) (string, error)
|
||||
// InstanceType returns the type of the specified instance.
|
||||
InstanceType(name types.NodeName) (string, error)
|
||||
InstanceType(ctx context.Context, name types.NodeName) (string, error)
|
||||
// InstanceTypeByProviderID returns the type of the specified instance.
|
||||
InstanceTypeByProviderID(providerID string) (string, error)
|
||||
InstanceTypeByProviderID(ctx context.Context, providerID string) (string, error)
|
||||
// AddSSHKeyToAllInstances adds an SSH public key as a legal identity for all instances
|
||||
// expected format for the key is standard ssh-keygen format: <protocol> <blob>
|
||||
AddSSHKeyToAllInstances(user string, keyData []byte) error
|
||||
AddSSHKeyToAllInstances(ctx context.Context, user string, keyData []byte) error
|
||||
// CurrentNodeName returns the name of the node we are currently running on
|
||||
// On most clouds (e.g. GCE) this is the hostname, so we provide the hostname
|
||||
CurrentNodeName(hostname string) (types.NodeName, error)
|
||||
CurrentNodeName(ctx context.Context, hostname string) (types.NodeName, error)
|
||||
// InstanceExistsByProviderID returns true if the instance for the given provider id still is running.
|
||||
// If false is returned with no error, the instance will be immediately deleted by the cloud controller manager.
|
||||
InstanceExistsByProviderID(providerID string) (bool, error)
|
||||
InstanceExistsByProviderID(ctx context.Context, providerID string) (bool, error)
|
||||
}
|
||||
|
||||
// Route is a representation of an advanced routing rule.
|
||||
|
|
@ -167,14 +168,14 @@ type Route struct {
|
|||
// Routes is an abstract, pluggable interface for advanced routing rules.
|
||||
type Routes interface {
|
||||
// ListRoutes lists all managed routes that belong to the specified clusterName
|
||||
ListRoutes(clusterName string) ([]*Route, error)
|
||||
ListRoutes(ctx context.Context, clusterName string) ([]*Route, error)
|
||||
// CreateRoute creates the described managed route
|
||||
// route.Name will be ignored, although the cloud-provider may use nameHint
|
||||
// to create a more user-meaningful name.
|
||||
CreateRoute(clusterName string, nameHint string, route *Route) error
|
||||
CreateRoute(ctx context.Context, clusterName string, nameHint string, route *Route) error
|
||||
// DeleteRoute deletes the specified managed route
|
||||
// Route should be as returned by ListRoutes
|
||||
DeleteRoute(clusterName string, route *Route) error
|
||||
DeleteRoute(ctx context.Context, clusterName string, route *Route) error
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
@ -192,23 +193,23 @@ type Zone struct {
|
|||
// Zones is an abstract, pluggable interface for zone enumeration.
|
||||
type Zones interface {
|
||||
// GetZone returns the Zone containing the current failure zone and locality region that the program is running in
|
||||
// In most cases, this method is called from the kubelet querying a local metadata service to aquire its zone.
|
||||
// In most cases, this method is called from the kubelet querying a local metadata service to acquire its zone.
|
||||
// For the case of external cloud providers, use GetZoneByProviderID or GetZoneByNodeName since GetZone
|
||||
// can no longer be called from the kubelets.
|
||||
GetZone() (Zone, error)
|
||||
GetZone(ctx context.Context) (Zone, error)
|
||||
|
||||
// GetZoneByProviderID returns the Zone containing the current zone and locality region of the node specified by providerId
|
||||
// This method is particularly used in the context of external cloud providers where node initialization must be down
|
||||
// outside the kubelets.
|
||||
GetZoneByProviderID(providerID string) (Zone, error)
|
||||
GetZoneByProviderID(ctx context.Context, providerID string) (Zone, error)
|
||||
|
||||
// GetZoneByNodeName returns the Zone containing the current zone and locality region of the node specified by node name
|
||||
// This method is particularly used in the context of external cloud providers where node initialization must be down
|
||||
// outside the kubelets.
|
||||
GetZoneByNodeName(nodeName types.NodeName) (Zone, error)
|
||||
GetZoneByNodeName(ctx context.Context, nodeName types.NodeName) (Zone, error)
|
||||
}
|
||||
|
||||
// PVLabeler is an abstract, pluggable interface for fetching labels for volumes
|
||||
type PVLabeler interface {
|
||||
GetLabelsForVolume(pv *v1.PersistentVolume) (map[string]string, error)
|
||||
GetLabelsForVolume(ctx context.Context, pv *v1.PersistentVolume) (map[string]string, error)
|
||||
}
|
||||
|
|
|
|||
2
vendor/k8s.io/kubernetes/pkg/cloudprovider/plugins.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/cloudprovider/plugins.go
generated
vendored
|
|
@ -64,7 +64,7 @@ func IsCloudProvider(name string) bool {
|
|||
// the name is unknown. The error return is only used if the named provider
|
||||
// was known but failed to initialize. The config parameter specifies the
|
||||
// io.Reader handler of the configuration file for the cloud provider, or nil
|
||||
// for no configuation.
|
||||
// for no configuration.
|
||||
func GetCloudProvider(name string, config io.Reader) (Interface, error) {
|
||||
providersMutex.Lock()
|
||||
defer providersMutex.Unlock()
|
||||
|
|
|
|||
4
vendor/k8s.io/kubernetes/pkg/controller/BUILD
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/controller/BUILD
generated
vendored
|
|
@ -13,7 +13,6 @@ go_test(
|
|||
"controller_utils_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/controller",
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/api/testapi:go_default_library",
|
||||
|
|
@ -62,7 +61,7 @@ go_library(
|
|||
"//pkg/util/taints:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/golang/groupcache/lru:go_default_library",
|
||||
"//vendor/k8s.io/api/apps/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/apps/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/authentication/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
|
|
@ -136,6 +135,7 @@ filegroup(
|
|||
"//pkg/controller/volume/expand:all-srcs",
|
||||
"//pkg/controller/volume/persistentvolume:all-srcs",
|
||||
"//pkg/controller/volume/pvcprotection:all-srcs",
|
||||
"//pkg/controller/volume/pvprotection:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
|
|
|||
16
vendor/k8s.io/kubernetes/pkg/controller/controller_ref_manager.go
generated
vendored
16
vendor/k8s.io/kubernetes/pkg/controller/controller_ref_manager.go
generated
vendored
|
|
@ -21,7 +21,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/golang/glog"
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
apps "k8s.io/api/apps/v1"
|
||||
"k8s.io/api/core/v1"
|
||||
extensions "k8s.io/api/extensions/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
|
|
@ -429,25 +429,25 @@ func NewControllerRevisionControllerRefManager(
|
|||
// * Adopt orphans if the selector matches.
|
||||
// * Release owned objects if the selector no longer matches.
|
||||
//
|
||||
// A non-nil error is returned if some form of reconciliation was attemped and
|
||||
// A non-nil error is returned if some form of reconciliation was attempted and
|
||||
// failed. Usually, controllers should try again later in case reconciliation
|
||||
// is still needed.
|
||||
//
|
||||
// If the error is nil, either the reconciliation succeeded, or no
|
||||
// reconciliation was necessary. The list of ControllerRevisions that you now own is
|
||||
// returned.
|
||||
func (m *ControllerRevisionControllerRefManager) ClaimControllerRevisions(histories []*appsv1beta1.ControllerRevision) ([]*appsv1beta1.ControllerRevision, error) {
|
||||
var claimed []*appsv1beta1.ControllerRevision
|
||||
func (m *ControllerRevisionControllerRefManager) ClaimControllerRevisions(histories []*apps.ControllerRevision) ([]*apps.ControllerRevision, error) {
|
||||
var claimed []*apps.ControllerRevision
|
||||
var errlist []error
|
||||
|
||||
match := func(obj metav1.Object) bool {
|
||||
return m.Selector.Matches(labels.Set(obj.GetLabels()))
|
||||
}
|
||||
adopt := func(obj metav1.Object) error {
|
||||
return m.AdoptControllerRevision(obj.(*appsv1beta1.ControllerRevision))
|
||||
return m.AdoptControllerRevision(obj.(*apps.ControllerRevision))
|
||||
}
|
||||
release := func(obj metav1.Object) error {
|
||||
return m.ReleaseControllerRevision(obj.(*appsv1beta1.ControllerRevision))
|
||||
return m.ReleaseControllerRevision(obj.(*apps.ControllerRevision))
|
||||
}
|
||||
|
||||
for _, h := range histories {
|
||||
|
|
@ -465,7 +465,7 @@ func (m *ControllerRevisionControllerRefManager) ClaimControllerRevisions(histor
|
|||
|
||||
// AdoptControllerRevision sends a patch to take control of the ControllerRevision. It returns the error if
|
||||
// the patching fails.
|
||||
func (m *ControllerRevisionControllerRefManager) AdoptControllerRevision(history *appsv1beta1.ControllerRevision) error {
|
||||
func (m *ControllerRevisionControllerRefManager) AdoptControllerRevision(history *apps.ControllerRevision) error {
|
||||
if err := m.CanAdopt(); err != nil {
|
||||
return fmt.Errorf("can't adopt ControllerRevision %v/%v (%v): %v", history.Namespace, history.Name, history.UID, err)
|
||||
}
|
||||
|
|
@ -480,7 +480,7 @@ func (m *ControllerRevisionControllerRefManager) AdoptControllerRevision(history
|
|||
|
||||
// ReleaseControllerRevision sends a patch to free the ControllerRevision from the control of its controller.
|
||||
// It returns the error if the patching fails. 404 and 422 errors are ignored.
|
||||
func (m *ControllerRevisionControllerRefManager) ReleaseControllerRevision(history *appsv1beta1.ControllerRevision) error {
|
||||
func (m *ControllerRevisionControllerRefManager) ReleaseControllerRevision(history *apps.ControllerRevision) error {
|
||||
glog.V(2).Infof("patching ControllerRevision %s_%s to remove its controllerRef to %s/%s:%s",
|
||||
history.Namespace, history.Name, m.controllerKind.GroupVersion(), m.controllerKind.Kind, m.Controller.GetName())
|
||||
deleteOwnerRefPatch := fmt.Sprintf(`{"metadata":{"ownerReferences":[{"$patch":"delete","uid":"%s"}],"uid":"%s"}}`, m.Controller.GetUID(), history.UID)
|
||||
|
|
|
|||
2
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/controller/controller_utils.go
generated
vendored
|
|
@ -64,7 +64,7 @@ const (
|
|||
// latency/pod at the scale of 3000 pods over 100 nodes.
|
||||
ExpectationsTimeout = 5 * time.Minute
|
||||
// When batching pod creates, SlowStartInitialBatchSize is the size of the
|
||||
// inital batch. The size of each successive batch is twice the size of
|
||||
// initial batch. The size of each successive batch is twice the size of
|
||||
// the previous batch. For example, for a value of 1, batch sizes would be
|
||||
// 1, 2, 4, 8, ... and for a value of 10, batch sizes would be
|
||||
// 10, 20, 40, 80, ... Setting the value higher means that quota denials
|
||||
|
|
|
|||
130
vendor/k8s.io/kubernetes/pkg/features/kube_features.go
generated
vendored
130
vendor/k8s.io/kubernetes/pkg/features/kube_features.go
generated
vendored
|
|
@ -33,18 +33,10 @@ const (
|
|||
// beta: v1.4
|
||||
AppArmor utilfeature.Feature = "AppArmor"
|
||||
|
||||
// owner: @girishkalele
|
||||
// alpha: v1.4
|
||||
ExternalTrafficLocalOnly utilfeature.Feature = "AllowExtTrafficLocalEndpoints"
|
||||
|
||||
// owner: @mtaufen
|
||||
// alpha: v1.4
|
||||
DynamicKubeletConfig utilfeature.Feature = "DynamicKubeletConfig"
|
||||
|
||||
// owner: @mtaufen
|
||||
// alpha: v1.8
|
||||
KubeletConfigFile utilfeature.Feature = "KubeletConfigFile"
|
||||
|
||||
// owner: @pweil-
|
||||
// alpha: v1.5
|
||||
//
|
||||
|
|
@ -72,10 +64,9 @@ const (
|
|||
Accelerators utilfeature.Feature = "Accelerators"
|
||||
|
||||
// owner: @jiayingz
|
||||
// alpha: v1.8
|
||||
// beta: v1.10
|
||||
//
|
||||
// Enables support for Device Plugins
|
||||
// Only Nvidia GPUs are tested as of v1.8.
|
||||
DevicePlugins utilfeature.Feature = "DevicePlugins"
|
||||
|
||||
// owner: @gmarek
|
||||
|
|
@ -107,7 +98,7 @@ const (
|
|||
PersistentLocalVolumes utilfeature.Feature = "PersistentLocalVolumes"
|
||||
|
||||
// owner: @jinxu
|
||||
// alpha: v1.7
|
||||
// beta: v1.10
|
||||
//
|
||||
// New local storage types to support local storage capacity isolation
|
||||
LocalStorageCapacityIsolation utilfeature.Feature = "LocalStorageCapacityIsolation"
|
||||
|
|
@ -118,11 +109,17 @@ const (
|
|||
ExpandPersistentVolumes utilfeature.Feature = "ExpandPersistentVolumes"
|
||||
|
||||
// owner: @verb
|
||||
// alpha: v1.8
|
||||
// alpha: v1.10
|
||||
//
|
||||
// Allows running a "debug container" in a pod namespaces to troubleshoot a running pod.
|
||||
DebugContainers utilfeature.Feature = "DebugContainers"
|
||||
|
||||
// owner: @verb
|
||||
// alpha: v1.10
|
||||
//
|
||||
// Allows all containers in a pod to share a process namespace.
|
||||
PodShareProcessNamespace utilfeature.Feature = "PodShareProcessNamespace"
|
||||
|
||||
// owner: @bsalamat
|
||||
// alpha: v1.8
|
||||
//
|
||||
|
|
@ -143,7 +140,7 @@ const (
|
|||
TaintNodesByCondition utilfeature.Feature = "TaintNodesByCondition"
|
||||
|
||||
// owner: @jsafrane
|
||||
// alpha: v1.8
|
||||
// beta: v1.10
|
||||
//
|
||||
// Enable mount propagation of volumes.
|
||||
MountPropagation utilfeature.Feature = "MountPropagation"
|
||||
|
|
@ -166,6 +163,13 @@ const (
|
|||
// Enable nodes to exclude themselves from service load balancers
|
||||
ServiceNodeExclusion utilfeature.Feature = "ServiceNodeExclusion"
|
||||
|
||||
// owner @brendandburns
|
||||
// deprecated: v1.10
|
||||
//
|
||||
// Enable the service proxy to contact external IP addresses. Note this feature is present
|
||||
// only for backward compatibility, it will be removed in the 1.11 release.
|
||||
ServiceProxyAllowExternalIPs utilfeature.Feature = "ServiceProxyAllowExternalIPs"
|
||||
|
||||
// owner: @jsafrane
|
||||
// alpha: v1.9
|
||||
//
|
||||
|
|
@ -186,7 +190,7 @@ const (
|
|||
CSIPersistentVolume utilfeature.Feature = "CSIPersistentVolume"
|
||||
|
||||
// owner @MrHohn
|
||||
// alpha: v1.9
|
||||
// beta: v1.10
|
||||
//
|
||||
// Support configurable pod DNS parameters.
|
||||
CustomPodDNS utilfeature.Feature = "CustomPodDNS"
|
||||
|
|
@ -198,10 +202,10 @@ const (
|
|||
BlockVolume utilfeature.Feature = "BlockVolume"
|
||||
|
||||
// owner: @pospispa
|
||||
// beta: v1.10
|
||||
//
|
||||
// alpha: v1.9
|
||||
// Postpone deletion of a persistent volume claim in case it is used by a pod
|
||||
PVCProtection utilfeature.Feature = "PVCProtection"
|
||||
// Postpone deletion of a PV or a PVC when they are being used
|
||||
StorageObjectInUseProtection utilfeature.Feature = "StorageObjectInUseProtection"
|
||||
|
||||
// owner: @aveshagarwal
|
||||
// alpha: v1.9
|
||||
|
|
@ -214,6 +218,62 @@ const (
|
|||
//
|
||||
// Implement IPVS-based in-cluster service load balancing
|
||||
SupportIPVSProxyMode utilfeature.Feature = "SupportIPVSProxyMode"
|
||||
|
||||
// owner: @dims
|
||||
// alpha: v1.10
|
||||
//
|
||||
// Implement support for limiting pids in pods
|
||||
SupportPodPidsLimit utilfeature.Feature = "SupportPodPidsLimit"
|
||||
|
||||
// owner: @feiskyer
|
||||
// alpha: v1.10
|
||||
//
|
||||
// Enable Hyper-V containers on Windows
|
||||
HyperVContainer utilfeature.Feature = "HyperVContainer"
|
||||
|
||||
// owner: @joelsmith
|
||||
// deprecated: v1.10
|
||||
//
|
||||
// Mount secret, configMap, downwardAPI and projected volumes ReadOnly. Note: this feature
|
||||
// gate is present only for backward compatibility, it will be removed in the 1.11 release.
|
||||
ReadOnlyAPIDataVolumes utilfeature.Feature = "ReadOnlyAPIDataVolumes"
|
||||
|
||||
// owner: @k82cn
|
||||
// alpha: v1.10
|
||||
//
|
||||
// Schedule DaemonSet Pods by default scheduler instead of DaemonSet controller
|
||||
ScheduleDaemonSetPods utilfeature.Feature = "ScheduleDaemonSetPods"
|
||||
|
||||
// owner: @mikedanese
|
||||
// alpha: v1.10
|
||||
//
|
||||
// Implement TokenRequest endpoint on service account resources.
|
||||
TokenRequest utilfeature.Feature = "TokenRequest"
|
||||
|
||||
// owner: @Random-Liu
|
||||
// alpha: v1.10
|
||||
//
|
||||
// Enable container log rotation for cri container runtime
|
||||
CRIContainerLogRotation utilfeature.Feature = "CRIContainerLogRotation"
|
||||
|
||||
// owner: @verult
|
||||
// beta: v1.10
|
||||
//
|
||||
// Enables the regional PD feature on GCE.
|
||||
GCERegionalPersistentDisk utilfeature.Feature = "GCERegionalPersistentDisk"
|
||||
|
||||
// owner: @krmayankk
|
||||
// alpha: v1.10
|
||||
//
|
||||
// Enables control over the primary group ID of containers' init processes.
|
||||
RunAsGroup utilfeature.Feature = "RunAsGroup"
|
||||
|
||||
// owner: @saad-ali
|
||||
// ga
|
||||
//
|
||||
// Allow mounting a subpath of a volume in a container
|
||||
// Do not remove this feature gate even though it's GA
|
||||
VolumeSubpath utilfeature.Feature = "VolumeSubpath"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
@ -224,36 +284,43 @@ func init() {
|
|||
// To add a new feature, define a key for it above and add it here. The features will be
|
||||
// available throughout Kubernetes binaries.
|
||||
var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureSpec{
|
||||
ExternalTrafficLocalOnly: {Default: true, PreRelease: utilfeature.GA},
|
||||
AppArmor: {Default: true, PreRelease: utilfeature.Beta},
|
||||
DynamicKubeletConfig: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
KubeletConfigFile: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
ExperimentalHostUserNamespaceDefaultingGate: {Default: false, PreRelease: utilfeature.Beta},
|
||||
ExperimentalCriticalPodAnnotation: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
Accelerators: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
DevicePlugins: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
DevicePlugins: {Default: true, PreRelease: utilfeature.Beta},
|
||||
TaintBasedEvictions: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
RotateKubeletServerCertificate: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
RotateKubeletClientCertificate: {Default: true, PreRelease: utilfeature.Beta},
|
||||
PersistentLocalVolumes: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
LocalStorageCapacityIsolation: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
PersistentLocalVolumes: {Default: true, PreRelease: utilfeature.Beta},
|
||||
LocalStorageCapacityIsolation: {Default: true, PreRelease: utilfeature.Beta},
|
||||
HugePages: {Default: true, PreRelease: utilfeature.Beta},
|
||||
DebugContainers: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
PodShareProcessNamespace: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
PodPriority: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
EnableEquivalenceClassCache: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
TaintNodesByCondition: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
MountPropagation: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
MountPropagation: {Default: true, PreRelease: utilfeature.Beta},
|
||||
ExpandPersistentVolumes: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
CPUManager: {Default: true, PreRelease: utilfeature.Beta},
|
||||
ServiceNodeExclusion: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
MountContainers: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
VolumeScheduling: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
CSIPersistentVolume: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
CustomPodDNS: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
VolumeScheduling: {Default: true, PreRelease: utilfeature.Beta},
|
||||
CSIPersistentVolume: {Default: true, PreRelease: utilfeature.Beta},
|
||||
CustomPodDNS: {Default: true, PreRelease: utilfeature.Beta},
|
||||
BlockVolume: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
PVCProtection: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
StorageObjectInUseProtection: {Default: true, PreRelease: utilfeature.Beta},
|
||||
ResourceLimitsPriorityFunction: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
SupportIPVSProxyMode: {Default: false, PreRelease: utilfeature.Beta},
|
||||
SupportIPVSProxyMode: {Default: true, PreRelease: utilfeature.Beta},
|
||||
SupportPodPidsLimit: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
HyperVContainer: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
ScheduleDaemonSetPods: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
TokenRequest: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
CRIContainerLogRotation: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
GCERegionalPersistentDisk: {Default: true, PreRelease: utilfeature.Beta},
|
||||
RunAsGroup: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
VolumeSubpath: {Default: true, PreRelease: utilfeature.GA},
|
||||
|
||||
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
|
||||
// unintentionally on either side:
|
||||
|
|
@ -265,5 +332,10 @@ var defaultKubernetesFeatureGates = map[utilfeature.Feature]utilfeature.FeatureS
|
|||
|
||||
// inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed
|
||||
// unintentionally on either side:
|
||||
apiextensionsfeatures.CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta},
|
||||
apiextensionsfeatures.CustomResourceValidation: {Default: true, PreRelease: utilfeature.Beta},
|
||||
apiextensionsfeatures.CustomResourceSubresources: {Default: false, PreRelease: utilfeature.Alpha},
|
||||
|
||||
// features that enable backwards compatibility but are scheduled to be removed
|
||||
ServiceProxyAllowExternalIPs: {Default: false, PreRelease: utilfeature.Deprecated},
|
||||
ReadOnlyAPIDataVolumes: {Default: true, PreRelease: utilfeature.Deprecated},
|
||||
}
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/fieldpath/BUILD
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/fieldpath/BUILD
generated
vendored
|
|
@ -23,7 +23,6 @@ go_test(
|
|||
name = "go_default_test",
|
||||
srcs = ["fieldpath_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/fieldpath",
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
|
|
|
|||
14
vendor/k8s.io/kubernetes/pkg/kubelet/BUILD
generated
vendored
14
vendor/k8s.io/kubernetes/pkg/kubelet/BUILD
generated
vendored
|
|
@ -42,7 +42,7 @@ go_library(
|
|||
"//pkg/fieldpath:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//pkg/kubelet/apis/cri:go_default_library",
|
||||
"//pkg/kubelet/apis/cri/v1alpha1/runtime:go_default_library",
|
||||
"//pkg/kubelet/apis/cri/runtime/v1alpha2:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||
"//pkg/kubelet/cadvisor:go_default_library",
|
||||
"//pkg/kubelet/certificate:go_default_library",
|
||||
|
|
@ -61,7 +61,9 @@ go_library(
|
|||
"//pkg/kubelet/kubeletconfig:go_default_library",
|
||||
"//pkg/kubelet/kuberuntime:go_default_library",
|
||||
"//pkg/kubelet/lifecycle:go_default_library",
|
||||
"//pkg/kubelet/logs:go_default_library",
|
||||
"//pkg/kubelet/metrics:go_default_library",
|
||||
"//pkg/kubelet/metrics/collectors:go_default_library",
|
||||
"//pkg/kubelet/mountpod:go_default_library",
|
||||
"//pkg/kubelet/network:go_default_library",
|
||||
"//pkg/kubelet/network/dns:go_default_library",
|
||||
|
|
@ -103,7 +105,7 @@ go_library(
|
|||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//pkg/volume/util/types:go_default_library",
|
||||
"//pkg/volume/util/volumehelper:go_default_library",
|
||||
"//pkg/volume/util/volumepathhandler:go_default_library",
|
||||
"//pkg/volume/validation:go_default_library",
|
||||
"//third_party/forked/golang/expansion:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
|
|
@ -162,14 +164,13 @@ go_test(
|
|||
"//conditions:default": [],
|
||||
}),
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet",
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/core/install:go_default_library",
|
||||
"//pkg/capabilities:go_default_library",
|
||||
"//pkg/cloudprovider/providers/fake:go_default_library",
|
||||
"//pkg/kubelet/apis:go_default_library",
|
||||
"//pkg/kubelet/apis/cri/v1alpha1/runtime:go_default_library",
|
||||
"//pkg/kubelet/apis/cri/runtime/v1alpha2:go_default_library",
|
||||
"//pkg/kubelet/apis/kubeletconfig:go_default_library",
|
||||
"//pkg/kubelet/cadvisor/testing:go_default_library",
|
||||
"//pkg/kubelet/cm:go_default_library",
|
||||
|
|
@ -181,6 +182,7 @@ go_test(
|
|||
"//pkg/kubelet/gpu:go_default_library",
|
||||
"//pkg/kubelet/images:go_default_library",
|
||||
"//pkg/kubelet/lifecycle:go_default_library",
|
||||
"//pkg/kubelet/logs:go_default_library",
|
||||
"//pkg/kubelet/network:go_default_library",
|
||||
"//pkg/kubelet/network/testing:go_default_library",
|
||||
"//pkg/kubelet/pleg:go_default_library",
|
||||
|
|
@ -205,7 +207,7 @@ go_test(
|
|||
"//pkg/volume:go_default_library",
|
||||
"//pkg/volume/host_path:go_default_library",
|
||||
"//pkg/volume/testing:go_default_library",
|
||||
"//pkg/volume/util/volumehelper:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/info/v1:go_default_library",
|
||||
"//vendor/github.com/google/cadvisor/info/v2:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
|
|
@ -268,6 +270,7 @@ filegroup(
|
|||
"//pkg/kubelet/kuberuntime:all-srcs",
|
||||
"//pkg/kubelet/leaky:all-srcs",
|
||||
"//pkg/kubelet/lifecycle:all-srcs",
|
||||
"//pkg/kubelet/logs:all-srcs",
|
||||
"//pkg/kubelet/metrics:all-srcs",
|
||||
"//pkg/kubelet/mountpod:all-srcs",
|
||||
"//pkg/kubelet/network:all-srcs",
|
||||
|
|
@ -278,7 +281,6 @@ filegroup(
|
|||
"//pkg/kubelet/qos:all-srcs",
|
||||
"//pkg/kubelet/remote:all-srcs",
|
||||
"//pkg/kubelet/rkt:all-srcs",
|
||||
"//pkg/kubelet/rktshim:all-srcs",
|
||||
"//pkg/kubelet/secret:all-srcs",
|
||||
"//pkg/kubelet/server:all-srcs",
|
||||
"//pkg/kubelet/stats:all-srcs",
|
||||
|
|
|
|||
15
vendor/k8s.io/kubernetes/pkg/kubelet/apis/BUILD
generated
vendored
15
vendor/k8s.io/kubernetes/pkg/kubelet/apis/BUILD
generated
vendored
|
|
@ -10,8 +10,20 @@ go_library(
|
|||
srcs = [
|
||||
"well_known_annotations.go",
|
||||
"well_known_labels.go",
|
||||
],
|
||||
] + select({
|
||||
"@io_bazel_rules_go//go/platform:windows": [
|
||||
"well_known_annotations_windows.go",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/apis",
|
||||
deps = select({
|
||||
"@io_bazel_rules_go//go/platform:windows": [
|
||||
"//pkg/features:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
)
|
||||
|
||||
filegroup(
|
||||
|
|
@ -27,6 +39,7 @@ filegroup(
|
|||
":package-srcs",
|
||||
"//pkg/kubelet/apis/cri:all-srcs",
|
||||
"//pkg/kubelet/apis/deviceplugin/v1alpha:all-srcs",
|
||||
"//pkg/kubelet/apis/deviceplugin/v1beta1:all-srcs",
|
||||
"//pkg/kubelet/apis/kubeletconfig:all-srcs",
|
||||
"//pkg/kubelet/apis/stats/v1alpha1:all-srcs",
|
||||
],
|
||||
|
|
|
|||
4
vendor/k8s.io/kubernetes/pkg/kubelet/apis/cri/BUILD
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/kubelet/apis/cri/BUILD
generated
vendored
|
|
@ -9,7 +9,7 @@ go_library(
|
|||
name = "go_default_library",
|
||||
srcs = ["services.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/apis/cri",
|
||||
deps = ["//pkg/kubelet/apis/cri/v1alpha1/runtime:go_default_library"],
|
||||
deps = ["//pkg/kubelet/apis/cri/runtime/v1alpha2:go_default_library"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
|
|
@ -23,8 +23,8 @@ filegroup(
|
|||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/kubelet/apis/cri/runtime/v1alpha2:all-srcs",
|
||||
"//pkg/kubelet/apis/cri/testing:all-srcs",
|
||||
"//pkg/kubelet/apis/cri/v1alpha1/runtime:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ go_library(
|
|||
"api.pb.go",
|
||||
"constants.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime",
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2",
|
||||
deps = [
|
||||
"//vendor/github.com/gogo/protobuf/gogoproto:go_default_library",
|
||||
"//vendor/github.com/gogo/protobuf/proto:go_default_library",
|
||||
|
|
@ -37,5 +37,4 @@ filegroup(
|
|||
filegroup(
|
||||
name = "go_default_library_protos",
|
||||
srcs = ["api.proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,7 +1,8 @@
|
|||
// To regenerate api.pb.go run hack/update-generated-runtime.sh
|
||||
syntax = 'proto3';
|
||||
|
||||
package runtime;
|
||||
package runtime.v1alpha2;
|
||||
option go_package = "v1alpha2";
|
||||
|
||||
import "github.com/gogo/protobuf/gogoproto/gogo.proto";
|
||||
|
||||
|
|
@ -63,6 +64,12 @@ service RuntimeService {
|
|||
rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {}
|
||||
// UpdateContainerResources updates ContainerConfig of the container.
|
||||
rpc UpdateContainerResources(UpdateContainerResourcesRequest) returns (UpdateContainerResourcesResponse) {}
|
||||
// ReopenContainerLog asks runtime to reopen the stdout/stderr log file
|
||||
// for the container. This is often called after the log file has been
|
||||
// rotated. If the container is not running, container runtime can choose
|
||||
// to either create a new log file and return nil, or return an error.
|
||||
// Once it returns error, new container log file MUST NOT be created.
|
||||
rpc ReopenContainerLog(ReopenContainerLogRequest) returns (ReopenContainerLogResponse) {}
|
||||
|
||||
// ExecSync runs a command in a container synchronously.
|
||||
rpc ExecSync(ExecSyncRequest) returns (ExecSyncResponse) {}
|
||||
|
|
@ -174,14 +181,39 @@ message Mount {
|
|||
MountPropagation propagation = 5;
|
||||
}
|
||||
|
||||
// A NamespaceMode describes the intended namespace configuration for each
|
||||
// of the namespaces (Network, PID, IPC) in NamespaceOption. Runtimes should
|
||||
// map these modes as appropriate for the technology underlying the runtime.
|
||||
enum NamespaceMode {
|
||||
// A POD namespace is common to all containers in a pod.
|
||||
// For example, a container with a PID namespace of POD expects to view
|
||||
// all of the processes in all of the containers in the pod.
|
||||
POD = 0;
|
||||
// A CONTAINER namespace is restricted to a single container.
|
||||
// For example, a container with a PID namespace of CONTAINER expects to
|
||||
// view only the processes in that container.
|
||||
CONTAINER = 1;
|
||||
// A NODE namespace is the namespace of the Kubernetes node.
|
||||
// For example, a container with a PID namespace of NODE expects to view
|
||||
// all of the processes on the host running the kubelet.
|
||||
NODE = 2;
|
||||
}
|
||||
|
||||
// NamespaceOption provides options for Linux namespaces.
|
||||
message NamespaceOption {
|
||||
// If set, use the host's network namespace.
|
||||
bool host_network = 1;
|
||||
// If set, use the host's PID namespace.
|
||||
bool host_pid = 2;
|
||||
// If set, use the host's IPC namespace.
|
||||
bool host_ipc = 3;
|
||||
// Network namespace for this container/sandbox.
|
||||
// Note: There is currently no way to set CONTAINER scoped network in the Kubernetes API.
|
||||
// Namespaces currently set by the kubelet: POD, NODE
|
||||
NamespaceMode network = 1;
|
||||
// PID namespace for this container/sandbox.
|
||||
// Note: The CRI default is POD, but the v1.PodSpec default is CONTAINER.
|
||||
// The kubelet's runtime manager will set this to CONTAINER explicitly for v1 pods.
|
||||
// Namespaces currently set by the kubelet: POD, CONTAINER, NODE
|
||||
NamespaceMode pid = 2;
|
||||
// IPC namespace for this container/sandbox.
|
||||
// Note: There is currently no way to set CONTAINER scoped IPC in the Kubernetes API.
|
||||
// Namespaces currently set by the kubelet: POD, NODE
|
||||
NamespaceMode ipc = 3;
|
||||
}
|
||||
|
||||
// Int64Value is the wrapper of int64.
|
||||
|
|
@ -203,6 +235,8 @@ message LinuxSandboxSecurityContext {
|
|||
SELinuxOption selinux_options = 2;
|
||||
// UID to run sandbox processes as, when applicable.
|
||||
Int64Value run_as_user = 3;
|
||||
// GID to run sandbox processes as, when applicable.
|
||||
Int64Value run_as_group = 8;
|
||||
// If set, the root filesystem of the sandbox is read-only.
|
||||
bool readonly_rootfs = 4;
|
||||
// List of groups applied to the first process run in the sandbox, in
|
||||
|
|
@ -384,7 +418,7 @@ message PodSandboxStatus {
|
|||
message PodSandboxStatusResponse {
|
||||
// Status of the PodSandbox.
|
||||
PodSandboxStatus status = 1;
|
||||
// Info is extra information of the PodSandbox. The key could be abitrary string, and
|
||||
// Info is extra information of the PodSandbox. The key could be arbitrary string, and
|
||||
// value should be in json format. The information could include anything useful for
|
||||
// debug, e.g. network namespace for linux container based container runtime.
|
||||
// It should only be returned non-empty when Verbose is true.
|
||||
|
|
@ -519,6 +553,9 @@ message LinuxContainerSecurityContext {
|
|||
// UID to run the container process as. Only one of run_as_user and
|
||||
// run_as_username can be specified at a time.
|
||||
Int64Value run_as_user = 5;
|
||||
// GID to run the container process as. Only one of run_as_group and
|
||||
// run_as_groupname can be specified at a time.
|
||||
Int64Value run_as_group = 12;
|
||||
// User name to run the container process as. If specified, the user MUST
|
||||
// exist in the container image (i.e. in the /etc/passwd inside the image),
|
||||
// and be resolved there by the runtime; otherwise, the runtime MUST error.
|
||||
|
|
@ -556,6 +593,26 @@ message LinuxContainerConfig {
|
|||
LinuxContainerSecurityContext security_context = 2;
|
||||
}
|
||||
|
||||
// WindowsContainerConfig contains platform-specific configuration for
|
||||
// Windows-based containers.
|
||||
message WindowsContainerConfig {
|
||||
// Resources specification for the container.
|
||||
WindowsContainerResources resources = 1;
|
||||
}
|
||||
|
||||
// WindowsContainerResources specifies Windows specific configuration for
|
||||
// resources.
|
||||
message WindowsContainerResources {
|
||||
// CPU shares (relative weight vs. other containers). Default: 0 (not specified).
|
||||
int64 cpu_shares = 1;
|
||||
// Number of CPUs available to the container. Default: 0 (not specified).
|
||||
int64 cpu_count = 2;
|
||||
// Specifies the portion of processor cycles that this container can use as a percentage times 100.
|
||||
int64 cpu_maximum = 3;
|
||||
// Memory limit in bytes. Default: 0 (not specified).
|
||||
int64 memory_limit_in_bytes = 4;
|
||||
}
|
||||
|
||||
// ContainerMetadata holds all necessary information for building the container
|
||||
// name. The container runtime is encouraged to expose the metadata in its user
|
||||
// interface for better user experience. E.g., runtime can construct a unique
|
||||
|
|
@ -643,6 +700,8 @@ message ContainerConfig {
|
|||
|
||||
// Configuration specific to Linux containers.
|
||||
LinuxContainerConfig linux = 15;
|
||||
// Configuration specific to Windows containers.
|
||||
WindowsContainerConfig windows = 16;
|
||||
}
|
||||
|
||||
message CreateContainerRequest {
|
||||
|
|
@ -800,7 +859,7 @@ message ContainerStatus {
|
|||
message ContainerStatusResponse {
|
||||
// Status of the container.
|
||||
ContainerStatus status = 1;
|
||||
// Info is extra information of the Container. The key could be abitrary string, and
|
||||
// Info is extra information of the Container. The key could be arbitrary string, and
|
||||
// value should be in json format. The information could include anything useful for
|
||||
// debug, e.g. pid for linux container based container runtime.
|
||||
// It should only be returned non-empty when Verbose is true.
|
||||
|
|
@ -941,7 +1000,7 @@ message ImageStatusRequest {
|
|||
message ImageStatusResponse {
|
||||
// Status of the image.
|
||||
Image image = 1;
|
||||
// Info is extra information of the Image. The key could be abitrary string, and
|
||||
// Info is extra information of the Image. The key could be arbitrary string, and
|
||||
// value should be in json format. The information could include anything useful
|
||||
// for debug, e.g. image config for oci image based container runtime.
|
||||
// It should only be returned non-empty when Verbose is true.
|
||||
|
|
@ -1036,7 +1095,7 @@ message StatusRequest {
|
|||
message StatusResponse {
|
||||
// Status of the Runtime.
|
||||
RuntimeStatus status = 1;
|
||||
// Info is extra information of the Runtime. The key could be abitrary string, and
|
||||
// Info is extra information of the Runtime. The key could be arbitrary string, and
|
||||
// value should be in json format. The information could include anything useful for
|
||||
// debug, e.g. plugins used by the container runtime.
|
||||
// It should only be returned non-empty when Verbose is true.
|
||||
|
|
@ -1051,18 +1110,18 @@ message UInt64Value {
|
|||
uint64 value = 1;
|
||||
}
|
||||
|
||||
// StorageIdentifier uniquely identify the storage..
|
||||
message StorageIdentifier{
|
||||
// UUID of the device.
|
||||
string uuid = 1;
|
||||
// FilesystemIdentifier uniquely identify the filesystem.
|
||||
message FilesystemIdentifier{
|
||||
// Mountpoint of a filesystem.
|
||||
string mountpoint = 1;
|
||||
}
|
||||
|
||||
// FilesystemUsage provides the filesystem usage information.
|
||||
message FilesystemUsage {
|
||||
// Timestamp in nanoseconds at which the information were collected. Must be > 0.
|
||||
int64 timestamp = 1;
|
||||
// The underlying storage of the filesystem.
|
||||
StorageIdentifier storage_id = 2;
|
||||
// The unique identifier of the filesystem.
|
||||
FilesystemIdentifier fs_id = 2;
|
||||
// UsedBytes represents the bytes used for images on the filesystem.
|
||||
// This may differ from the total bytes used on the filesystem and may not
|
||||
// equal CapacityBytes - AvailableBytes.
|
||||
|
|
@ -1153,3 +1212,11 @@ message MemoryUsage {
|
|||
// The amount of working set memory in bytes.
|
||||
UInt64Value working_set_bytes = 2;
|
||||
}
|
||||
|
||||
message ReopenContainerLogRequest {
|
||||
// ID of the container for which to reopen the log.
|
||||
string container_id = 1;
|
||||
}
|
||||
|
||||
message ReopenContainerLogResponse{
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package runtime
|
||||
package v1alpha2
|
||||
|
||||
// This file contains all constants defined in CRI.
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ const (
|
|||
|
||||
// LogTag is the tag of a log line in CRI container log.
|
||||
// Currently defined log tags:
|
||||
// * First tag: Partial/End - P/E.
|
||||
// * First tag: Partial/Full - P/F.
|
||||
// The field in the container log format can be extended to include multiple
|
||||
// tags by using a delimiter, but changes should be rare. If it becomes clear
|
||||
// that better extensibility is desired, a more extensible format (e.g., json)
|
||||
8
vendor/k8s.io/kubernetes/pkg/kubelet/apis/cri/services.go
generated
vendored
8
vendor/k8s.io/kubernetes/pkg/kubelet/apis/cri/services.go
generated
vendored
|
|
@ -19,7 +19,7 @@ package cri
|
|||
import (
|
||||
"time"
|
||||
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
)
|
||||
|
||||
// RuntimeVersioner contains methods for runtime name, version and API version.
|
||||
|
|
@ -52,6 +52,10 @@ type ContainerManager interface {
|
|||
Exec(*runtimeapi.ExecRequest) (*runtimeapi.ExecResponse, error)
|
||||
// Attach prepares a streaming endpoint to attach to a running container, and returns the address.
|
||||
Attach(req *runtimeapi.AttachRequest) (*runtimeapi.AttachResponse, error)
|
||||
// ReopenContainerLog asks runtime to reopen the stdout/stderr log file
|
||||
// for the container. If it returns error, new container log file MUST NOT
|
||||
// be created.
|
||||
ReopenContainerLog(ContainerID string) error
|
||||
}
|
||||
|
||||
// PodSandboxManager contains methods for operating on PodSandboxes. The methods
|
||||
|
|
@ -74,7 +78,7 @@ type PodSandboxManager interface {
|
|||
PortForward(*runtimeapi.PortForwardRequest) (*runtimeapi.PortForwardResponse, error)
|
||||
}
|
||||
|
||||
// ContainerStatsManager contains methods for retriving the container
|
||||
// ContainerStatsManager contains methods for retrieving the container
|
||||
// statistics.
|
||||
type ContainerStatsManager interface {
|
||||
// ContainerStats returns stats of the container. If the container does not
|
||||
|
|
|
|||
41
vendor/k8s.io/kubernetes/pkg/kubelet/apis/well_known_annotations_windows.go
generated
vendored
Normal file
41
vendor/k8s.io/kubernetes/pkg/kubelet/apis/well_known_annotations_windows.go
generated
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// +build windows
|
||||
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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 apis
|
||||
|
||||
import (
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
)
|
||||
|
||||
const (
|
||||
// HypervIsolationAnnotationKey and HypervIsolationValue are used to run windows containers with hyperv isolation.
|
||||
// Refer https://aka.ms/hyperv-container.
|
||||
HypervIsolationAnnotationKey = "experimental.windows.kubernetes.io/isolation-type"
|
||||
HypervIsolationValue = "hyperv"
|
||||
)
|
||||
|
||||
// ShouldIsolatedByHyperV returns true if a windows container should be run with hyperv isolation.
|
||||
func ShouldIsolatedByHyperV(annotations map[string]string) bool {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.HyperVContainer) {
|
||||
return false
|
||||
}
|
||||
|
||||
v, ok := annotations[HypervIsolationAnnotationKey]
|
||||
return ok && v == HypervIsolationValue
|
||||
}
|
||||
4
vendor/k8s.io/kubernetes/pkg/kubelet/container/BUILD
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/kubelet/container/BUILD
generated
vendored
|
|
@ -54,7 +54,7 @@ go_library(
|
|||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/kubelet/apis/cri/v1alpha1/runtime:go_default_library",
|
||||
"//pkg/kubelet/apis/cri/runtime/v1alpha2:go_default_library",
|
||||
"//pkg/kubelet/util/format:go_default_library",
|
||||
"//pkg/kubelet/util/ioutils:go_default_library",
|
||||
"//pkg/util/hash:go_default_library",
|
||||
|
|
@ -88,7 +88,6 @@ go_test(
|
|||
"sync_result_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/container",
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/core/install:go_default_library",
|
||||
|
|
@ -102,7 +101,6 @@ go_test(
|
|||
go_test(
|
||||
name = "go_default_xtest",
|
||||
srcs = ["runtime_cache_test.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/container_test",
|
||||
deps = [
|
||||
":go_default_library",
|
||||
"//pkg/kubelet/container/testing:go_default_library",
|
||||
|
|
|
|||
5
vendor/k8s.io/kubernetes/pkg/kubelet/container/container_gc.go
generated
vendored
5
vendor/k8s.io/kubernetes/pkg/kubelet/container/container_gc.go
generated
vendored
|
|
@ -19,6 +19,8 @@ package container
|
|||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// Specified a policy for garbage collecting containers.
|
||||
|
|
@ -58,7 +60,7 @@ type realContainerGC struct {
|
|||
// Policy for garbage collection.
|
||||
policy ContainerGCPolicy
|
||||
|
||||
// sourcesReadyProvider provides the readyness of kubelet configuration sources.
|
||||
// sourcesReadyProvider provides the readiness of kubelet configuration sources.
|
||||
sourcesReadyProvider SourcesReadyProvider
|
||||
}
|
||||
|
||||
|
|
@ -80,5 +82,6 @@ func (cgc *realContainerGC) GarbageCollect() error {
|
|||
}
|
||||
|
||||
func (cgc *realContainerGC) DeleteAllUnusedContainers() error {
|
||||
glog.Infof("attempting to delete unused containers")
|
||||
return cgc.runtime.GarbageCollect(cgc.policy, cgc.sourcesReadyProvider.AllReady(), true)
|
||||
}
|
||||
|
|
|
|||
8
vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go
generated
vendored
8
vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go
generated
vendored
|
|
@ -31,7 +31,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/tools/record"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/ioutils"
|
||||
hashutil "k8s.io/kubernetes/pkg/util/hash"
|
||||
|
|
@ -46,9 +46,9 @@ type HandlerRunner interface {
|
|||
// RuntimeHelper wraps kubelet to make container runtime
|
||||
// able to get necessary informations like the RunContainerOptions, DNS settings, Host IP.
|
||||
type RuntimeHelper interface {
|
||||
GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (contOpts *RunContainerOptions, err error)
|
||||
GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (contOpts *RunContainerOptions, cleanupAction func(), err error)
|
||||
GetPodDNS(pod *v1.Pod) (dnsConfig *runtimeapi.DNSConfig, err error)
|
||||
// GetPodCgroupParent returns the CgroupName identifer, and its literal cgroupfs form on the host
|
||||
// GetPodCgroupParent returns the CgroupName identifier, and its literal cgroupfs form on the host
|
||||
// of a pod.
|
||||
GetPodCgroupParent(pod *v1.Pod) string
|
||||
GetPodDir(podUID types.UID) string
|
||||
|
|
@ -302,7 +302,7 @@ func GetContainerSpec(pod *v1.Pod, containerName string) *v1.Container {
|
|||
|
||||
// HasPrivilegedContainer returns true if any of the containers in the pod are privileged.
|
||||
func HasPrivilegedContainer(pod *v1.Pod) bool {
|
||||
for _, c := range pod.Spec.Containers {
|
||||
for _, c := range append(pod.Spec.Containers, pod.Spec.InitContainers...) {
|
||||
if c.SecurityContext != nil &&
|
||||
c.SecurityContext.Privileged != nil &&
|
||||
*c.SecurityContext.Privileged {
|
||||
|
|
|
|||
14
vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers_test.go
generated
vendored
14
vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers_test.go
generated
vendored
|
|
@ -254,6 +254,20 @@ func TestHasPrivilegedContainer(t *testing.T) {
|
|||
t.Errorf("%s expected %t but got %t", k, v.expected, actual)
|
||||
}
|
||||
}
|
||||
// Test init containers as well.
|
||||
for k, v := range tests {
|
||||
pod := &v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
InitContainers: []v1.Container{
|
||||
{SecurityContext: v.securityContext},
|
||||
},
|
||||
},
|
||||
}
|
||||
actual := HasPrivilegedContainer(pod)
|
||||
if actual != v.expected {
|
||||
t.Errorf("%s expected %t but got %t", k, v.expected, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakePortMappings(t *testing.T) {
|
||||
|
|
|
|||
21
vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go
generated
vendored
21
vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go
generated
vendored
|
|
@ -29,7 +29,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/tools/remotecommand"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
)
|
||||
|
||||
|
|
@ -265,6 +265,13 @@ const (
|
|||
ContainerStateUnknown ContainerState = "unknown"
|
||||
)
|
||||
|
||||
type ContainerType string
|
||||
|
||||
const (
|
||||
ContainerTypeInit ContainerType = "INIT"
|
||||
ContainerTypeRegular ContainerType = "REGULAR"
|
||||
)
|
||||
|
||||
// Container provides the runtime information for a container, such as ID, hash,
|
||||
// state of the container.
|
||||
type Container struct {
|
||||
|
|
@ -375,6 +382,11 @@ type EnvVar struct {
|
|||
Value string
|
||||
}
|
||||
|
||||
type Annotation struct {
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
||||
type Mount struct {
|
||||
// Name of the volume mount.
|
||||
// TODO(yifan): Remove this field, as this is not representing the unique name of the mount,
|
||||
|
|
@ -424,6 +436,10 @@ type RunContainerOptions struct {
|
|||
Devices []DeviceInfo
|
||||
// The port mappings for the containers.
|
||||
PortMappings []PortMapping
|
||||
// The annotations for the container
|
||||
// These annotations are generated by other components (i.e.,
|
||||
// not users). Currently, only device plugins populate the annotations.
|
||||
Annotations []Annotation
|
||||
// If the container has specified the TerminationMessagePath, then
|
||||
// this directory will be used to create and mount the log file to
|
||||
// container.TerminationMessagePath
|
||||
|
|
@ -454,6 +470,9 @@ type VolumeInfo struct {
|
|||
// Whether the volume permission is set to read-only or not
|
||||
// This value is passed from volume.spec
|
||||
ReadOnly bool
|
||||
// Inner volume spec name, which is the PV name if used, otherwise
|
||||
// it is the same as the outer volume spec name.
|
||||
InnerVolumeSpecName string
|
||||
}
|
||||
|
||||
type VolumeMap map[string]VolumeInfo
|
||||
|
|
|
|||
119
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go
generated
vendored
119
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet.go
generated
vendored
|
|
@ -17,8 +17,10 @@ limitations under the License.
|
|||
package kubelet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
|
@ -73,7 +75,9 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubelet/kubeletconfig"
|
||||
"k8s.io/kubernetes/pkg/kubelet/kuberuntime"
|
||||
"k8s.io/kubernetes/pkg/kubelet/lifecycle"
|
||||
"k8s.io/kubernetes/pkg/kubelet/logs"
|
||||
"k8s.io/kubernetes/pkg/kubelet/metrics"
|
||||
"k8s.io/kubernetes/pkg/kubelet/metrics/collectors"
|
||||
"k8s.io/kubernetes/pkg/kubelet/network"
|
||||
"k8s.io/kubernetes/pkg/kubelet/network/dns"
|
||||
"k8s.io/kubernetes/pkg/kubelet/pleg"
|
||||
|
|
@ -252,8 +256,8 @@ type Dependencies struct {
|
|||
// KubeletConfiguration or returns an error.
|
||||
func makePodSourceConfig(kubeCfg *kubeletconfiginternal.KubeletConfiguration, kubeDeps *Dependencies, nodeName types.NodeName, bootstrapCheckpointPath string) (*config.PodConfig, error) {
|
||||
manifestURLHeader := make(http.Header)
|
||||
if len(kubeCfg.ManifestURLHeader) > 0 {
|
||||
for k, v := range kubeCfg.ManifestURLHeader {
|
||||
if len(kubeCfg.StaticPodURLHeader) > 0 {
|
||||
for k, v := range kubeCfg.StaticPodURLHeader {
|
||||
for i := range v {
|
||||
manifestURLHeader.Add(k, v[i])
|
||||
}
|
||||
|
|
@ -264,23 +268,25 @@ func makePodSourceConfig(kubeCfg *kubeletconfiginternal.KubeletConfiguration, ku
|
|||
cfg := config.NewPodConfig(config.PodConfigNotificationIncremental, kubeDeps.Recorder)
|
||||
|
||||
// define file config source
|
||||
if kubeCfg.PodManifestPath != "" {
|
||||
glog.Infof("Adding manifest path: %v", kubeCfg.PodManifestPath)
|
||||
config.NewSourceFile(kubeCfg.PodManifestPath, nodeName, kubeCfg.FileCheckFrequency.Duration, cfg.Channel(kubetypes.FileSource))
|
||||
if kubeCfg.StaticPodPath != "" {
|
||||
glog.Infof("Adding pod path: %v", kubeCfg.StaticPodPath)
|
||||
config.NewSourceFile(kubeCfg.StaticPodPath, nodeName, kubeCfg.FileCheckFrequency.Duration, cfg.Channel(kubetypes.FileSource))
|
||||
}
|
||||
|
||||
// define url config source
|
||||
if kubeCfg.ManifestURL != "" {
|
||||
glog.Infof("Adding manifest url %q with HTTP header %v", kubeCfg.ManifestURL, manifestURLHeader)
|
||||
config.NewSourceURL(kubeCfg.ManifestURL, manifestURLHeader, nodeName, kubeCfg.HTTPCheckFrequency.Duration, cfg.Channel(kubetypes.HTTPSource))
|
||||
if kubeCfg.StaticPodURL != "" {
|
||||
glog.Infof("Adding pod url %q with HTTP header %v", kubeCfg.StaticPodURL, manifestURLHeader)
|
||||
config.NewSourceURL(kubeCfg.StaticPodURL, manifestURLHeader, nodeName, kubeCfg.HTTPCheckFrequency.Duration, cfg.Channel(kubetypes.HTTPSource))
|
||||
}
|
||||
|
||||
// Restore from the checkpoint path
|
||||
// NOTE: This MUST happen before creating the apiserver source
|
||||
// below, or the checkpoint would override the source of truth.
|
||||
updatechannel := cfg.Channel(kubetypes.ApiserverSource)
|
||||
|
||||
var updatechannel chan<- interface{}
|
||||
if bootstrapCheckpointPath != "" {
|
||||
glog.Infof("Adding checkpoint path: %v", bootstrapCheckpointPath)
|
||||
updatechannel = cfg.Channel(kubetypes.ApiserverSource)
|
||||
err := cfg.Restore(bootstrapCheckpointPath, updatechannel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -289,6 +295,9 @@ func makePodSourceConfig(kubeCfg *kubeletconfiginternal.KubeletConfiguration, ku
|
|||
|
||||
if kubeDeps.KubeClient != nil {
|
||||
glog.Infof("Watching apiserver")
|
||||
if updatechannel == nil {
|
||||
updatechannel = cfg.Channel(kubetypes.ApiserverSource)
|
||||
}
|
||||
config.NewSourceApiserver(kubeDeps.KubeClient, nodeName, updatechannel)
|
||||
}
|
||||
return cfg, nil
|
||||
|
|
@ -369,7 +378,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||
return nil, fmt.Errorf("failed to get instances from cloud provider")
|
||||
}
|
||||
|
||||
nodeName, err = instances.CurrentNodeName(hostname)
|
||||
nodeName, err = instances.CurrentNodeName(context.TODO(), hostname)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error fetching current instance name from cloud provider: %v", err)
|
||||
}
|
||||
|
|
@ -377,7 +386,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||
glog.V(2).Infof("cloud provider determined current node name to be %s", nodeName)
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.RotateKubeletServerCertificate) {
|
||||
nodeAddresses, err := instances.NodeAddresses(nodeName)
|
||||
nodeAddresses, err := instances.NodeAddresses(context.TODO(), nodeName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get the addresses of the current instance from the cloud provider: %v", err)
|
||||
}
|
||||
|
|
@ -551,11 +560,11 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||
return nil, err
|
||||
}
|
||||
klet.networkPlugin = plug
|
||||
|
||||
machineInfo, err := klet.GetCachedMachineInfo()
|
||||
machineInfo, err := klet.cadvisor.MachineInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
klet.machineInfo = machineInfo
|
||||
|
||||
imageBackOff := flowcontrol.NewBackOff(backOffPeriod, MaxContainerBackOff)
|
||||
|
||||
|
|
@ -590,6 +599,10 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||
var nl *NoOpLegacyHost
|
||||
pluginSettings.LegacyRuntimeHost = nl
|
||||
|
||||
if containerRuntime == kubetypes.RktContainerRuntime {
|
||||
glog.Warningln("rktnetes has been deprecated in favor of rktlet. Please see https://github.com/kubernetes-incubator/rktlet for more information.")
|
||||
}
|
||||
|
||||
// rktnetes cannot be run with CRI.
|
||||
if containerRuntime != kubetypes.RktContainerRuntime {
|
||||
// kubelet defers to the runtime shim to setup networking. Setting
|
||||
|
|
@ -610,9 +623,6 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := ds.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// For now, the CRI shim redirects the streaming requests to the
|
||||
// kubelet, which handles the requests using DockerService..
|
||||
klet.criHandler = ds
|
||||
|
|
@ -633,8 +643,8 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||
return nil, err
|
||||
}
|
||||
if !supported {
|
||||
klet.dockerLegacyService = ds.NewDockerLegacyService()
|
||||
legacyLogProvider = dockershim.NewLegacyLogProvider(klet.dockerLegacyService)
|
||||
klet.dockerLegacyService = ds
|
||||
legacyLogProvider = ds
|
||||
}
|
||||
case kubetypes.RemoteContainerRuntime:
|
||||
// No-op.
|
||||
|
|
@ -687,7 +697,8 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||
klet.podManager,
|
||||
klet.runtimeCache,
|
||||
runtimeService,
|
||||
imageService)
|
||||
imageService,
|
||||
stats.NewLogMetricsService())
|
||||
}
|
||||
} else {
|
||||
// rkt uses the legacy, non-CRI, integration. Configure it the old way.
|
||||
|
|
@ -743,12 +754,27 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||
klet.containerDeletor = newPodContainerDeletor(klet.containerRuntime, integer.IntMax(containerGCPolicy.MaxPerPodContainer, minDeadContainerInPod))
|
||||
|
||||
// setup imageManager
|
||||
imageManager, err := images.NewImageGCManager(klet.containerRuntime, klet.StatsProvider, kubeDeps.Recorder, nodeRef, imageGCPolicy)
|
||||
imageManager, err := images.NewImageGCManager(klet.containerRuntime, klet.StatsProvider, kubeDeps.Recorder, nodeRef, imageGCPolicy, crOptions.PodSandboxImage)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize image manager: %v", err)
|
||||
}
|
||||
klet.imageManager = imageManager
|
||||
|
||||
if containerRuntime == kubetypes.RemoteContainerRuntime && utilfeature.DefaultFeatureGate.Enabled(features.CRIContainerLogRotation) {
|
||||
// setup containerLogManager for CRI container runtime
|
||||
containerLogManager, err := logs.NewContainerLogManager(
|
||||
klet.runtimeService,
|
||||
kubeCfg.ContainerLogMaxSize,
|
||||
int(kubeCfg.ContainerLogMaxFiles),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize container log manager: %v", err)
|
||||
}
|
||||
klet.containerLogManager = containerLogManager
|
||||
} else {
|
||||
klet.containerLogManager = logs.NewStubContainerLogManager()
|
||||
}
|
||||
|
||||
klet.statusManager = status.NewManager(klet.kubeClient, klet.podManager, klet)
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.RotateKubeletServerCertificate) && kubeDeps.TLSOptions != nil {
|
||||
|
|
@ -773,7 +799,7 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||
kubeDeps.TLSOptions.Config.GetCertificate = func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
cert := klet.serverCertificateManager.Current()
|
||||
if cert == nil {
|
||||
return nil, fmt.Errorf("no certificate available")
|
||||
return nil, fmt.Errorf("no serving certificate available for the kubelet")
|
||||
}
|
||||
return cert, nil
|
||||
}
|
||||
|
|
@ -984,6 +1010,9 @@ type Kubelet struct {
|
|||
// Manager for image garbage collection.
|
||||
imageManager images.ImageGCManager
|
||||
|
||||
// Manager for container logs.
|
||||
containerLogManager logs.ContainerLogManager
|
||||
|
||||
// Secret manager.
|
||||
secretManager secret.Manager
|
||||
|
||||
|
|
@ -1264,7 +1293,7 @@ func (kl *Kubelet) StartGarbageCollection() {
|
|||
// Note that the modules here must not depend on modules that are not initialized here.
|
||||
func (kl *Kubelet) initializeModules() error {
|
||||
// Prometheus metrics.
|
||||
metrics.Register(kl.runtimeCache)
|
||||
metrics.Register(kl.runtimeCache, collectors.NewVolumeStatsCollector(kl))
|
||||
|
||||
// Setup filesystem directories.
|
||||
if err := kl.setupDataDirs(); err != nil {
|
||||
|
|
@ -1286,16 +1315,6 @@ func (kl *Kubelet) initializeModules() error {
|
|||
kl.serverCertificateManager.Start()
|
||||
}
|
||||
|
||||
// Start container manager.
|
||||
node, err := kl.getNodeAnyWay()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Kubelet failed to get node info: %v", err)
|
||||
}
|
||||
|
||||
if err := kl.containerManager.Start(node, kl.GetActivePods, kl.sourcesReady, kl.statusManager, kl.runtimeService); err != nil {
|
||||
return fmt.Errorf("Failed to start ContainerManager %v", err)
|
||||
}
|
||||
|
||||
// Start out of memory watcher.
|
||||
if err := kl.oomWatcher.Start(kl.nodeRef); err != nil {
|
||||
return fmt.Errorf("Failed to start OOM watcher %v", err)
|
||||
|
|
@ -1319,8 +1338,27 @@ func (kl *Kubelet) initializeRuntimeDependentModules() {
|
|||
// TODO(random-liu): Add backoff logic in the babysitter
|
||||
glog.Fatalf("Failed to start cAdvisor %v", err)
|
||||
}
|
||||
|
||||
// trigger on-demand stats collection once so that we have capacity information for ephemeral storage.
|
||||
// ignore any errors, since if stats collection is not successful, the container manager will fail to start below.
|
||||
kl.StatsProvider.GetCgroupStats("/", true)
|
||||
// Start container manager.
|
||||
node, err := kl.getNodeAnyWay()
|
||||
if err != nil {
|
||||
// Fail kubelet and rely on the babysitter to retry starting kubelet.
|
||||
glog.Fatalf("Kubelet failed to get node info: %v", err)
|
||||
}
|
||||
// containerManager must start after cAdvisor because it needs filesystem capacity information
|
||||
if err := kl.containerManager.Start(node, kl.GetActivePods, kl.sourcesReady, kl.statusManager, kl.runtimeService); err != nil {
|
||||
// Fail kubelet and rely on the babysitter to retry starting kubelet.
|
||||
glog.Fatalf("Failed to start ContainerManager %v", err)
|
||||
}
|
||||
// eviction manager must start after cadvisor because it needs to know if the container runtime has a dedicated imagefs
|
||||
kl.evictionManager.Start(kl.cadvisor, kl.GetActivePods, kl.podResourcesAreReclaimed, kl.containerManager, evictionMonitoringPeriod)
|
||||
kl.evictionManager.Start(kl.StatsProvider, kl.GetActivePods, kl.podResourcesAreReclaimed, evictionMonitoringPeriod)
|
||||
|
||||
// container log manager must start after container runtime is up to retrieve information from container runtime
|
||||
// and inform container to reopen log file after log rotation.
|
||||
kl.containerLogManager.Start()
|
||||
}
|
||||
|
||||
// Run starts the kubelet reacting to config updates
|
||||
|
|
@ -1334,8 +1372,7 @@ func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) {
|
|||
|
||||
if err := kl.initializeModules(); err != nil {
|
||||
kl.recorder.Eventf(kl.nodeRef, v1.EventTypeWarning, events.KubeletSetupFailed, err.Error())
|
||||
glog.Error(err)
|
||||
kl.runtimeState.setInitError(err)
|
||||
glog.Fatal(err)
|
||||
}
|
||||
|
||||
// Start volume manager
|
||||
|
|
@ -1746,12 +1783,22 @@ func (kl *Kubelet) syncLoop(updates <-chan kubetypes.PodUpdate, handler SyncHand
|
|||
housekeepingTicker := time.NewTicker(housekeepingPeriod)
|
||||
defer housekeepingTicker.Stop()
|
||||
plegCh := kl.pleg.Watch()
|
||||
const (
|
||||
base = 100 * time.Millisecond
|
||||
max = 5 * time.Second
|
||||
factor = 2
|
||||
)
|
||||
duration := base
|
||||
for {
|
||||
if rs := kl.runtimeState.runtimeErrors(); len(rs) != 0 {
|
||||
glog.Infof("skipping pod synchronization - %v", rs)
|
||||
time.Sleep(5 * time.Second)
|
||||
// exponential backoff
|
||||
time.Sleep(duration)
|
||||
duration = time.Duration(math.Min(float64(max), factor*float64(duration)))
|
||||
continue
|
||||
}
|
||||
// reset backoff if we have a success
|
||||
duration = base
|
||||
|
||||
kl.syncLoopMonitor.Store(kl.clock.Now())
|
||||
if !kl.syncLoopIteration(updates, handler, syncTicker.C, housekeepingTicker.C, plegCh) {
|
||||
|
|
|
|||
30
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_getters.go
generated
vendored
30
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_getters.go
generated
vendored
|
|
@ -211,6 +211,11 @@ func (kl *Kubelet) GetNodeConfig() cm.NodeConfig {
|
|||
return kl.containerManager.GetNodeConfig()
|
||||
}
|
||||
|
||||
// GetPodCgroupRoot returns the listeral cgroupfs value for the cgroup containing all pods
|
||||
func (kl *Kubelet) GetPodCgroupRoot() string {
|
||||
return kl.containerManager.GetPodCgroupRoot()
|
||||
}
|
||||
|
||||
// GetHostIP returns host IP or nil in case of error.
|
||||
func (kl *Kubelet) GetHostIP() (net.IP, error) {
|
||||
node, err := kl.GetNode()
|
||||
|
|
@ -269,6 +274,24 @@ func (kl *Kubelet) getPodVolumePathListFromDisk(podUID types.UID) ([]string, err
|
|||
return volumes, nil
|
||||
}
|
||||
|
||||
func (kl *Kubelet) getMountedVolumePathListFromDisk(podUID types.UID) ([]string, error) {
|
||||
mountedVolumes := []string{}
|
||||
volumePaths, err := kl.getPodVolumePathListFromDisk(podUID)
|
||||
if err != nil {
|
||||
return mountedVolumes, err
|
||||
}
|
||||
for _, volumePath := range volumePaths {
|
||||
isNotMount, err := kl.mounter.IsLikelyNotMountPoint(volumePath)
|
||||
if err != nil {
|
||||
return mountedVolumes, err
|
||||
}
|
||||
if !isNotMount {
|
||||
mountedVolumes = append(mountedVolumes, volumePath)
|
||||
}
|
||||
}
|
||||
return mountedVolumes, nil
|
||||
}
|
||||
|
||||
// GetVersionInfo returns information about the version of cAdvisor in use.
|
||||
func (kl *Kubelet) GetVersionInfo() (*cadvisorapiv1.VersionInfo, error) {
|
||||
return kl.cadvisor.VersionInfo()
|
||||
|
|
@ -276,12 +299,5 @@ func (kl *Kubelet) GetVersionInfo() (*cadvisorapiv1.VersionInfo, error) {
|
|||
|
||||
// GetCachedMachineInfo assumes that the machine info can't change without a reboot
|
||||
func (kl *Kubelet) GetCachedMachineInfo() (*cadvisorapiv1.MachineInfo, error) {
|
||||
if kl.machineInfo == nil {
|
||||
info, err := kl.cadvisor.MachineInfo()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
kl.machineInfo = info
|
||||
}
|
||||
return kl.machineInfo, nil
|
||||
}
|
||||
|
|
|
|||
4
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network.go
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_network.go
generated
vendored
|
|
@ -22,7 +22,7 @@ import (
|
|||
"github.com/golang/glog"
|
||||
"k8s.io/api/core/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
"k8s.io/kubernetes/pkg/kubelet/apis/kubeletconfig"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
"k8s.io/kubernetes/pkg/kubelet/network"
|
||||
|
|
@ -282,7 +282,7 @@ func getIPTablesMark(bit int) string {
|
|||
return fmt.Sprintf("%#08x/%#08x", value, value)
|
||||
}
|
||||
|
||||
// GetPodDNS returns DNS setttings for the pod.
|
||||
// GetPodDNS returns DNS settings for the pod.
|
||||
// This function is defined in kubecontainer.RuntimeHelper interface so we
|
||||
// have to implement it.
|
||||
func (kl *Kubelet) GetPodDNS(pod *v1.Pod) (*runtimeapi.DNSConfig, error) {
|
||||
|
|
|
|||
148
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status.go
generated
vendored
148
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status.go
generated
vendored
|
|
@ -17,12 +17,13 @@ limitations under the License.
|
|||
package kubelet
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
goruntime "runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
|
@ -41,11 +42,10 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubelet/cadvisor"
|
||||
"k8s.io/kubernetes/pkg/kubelet/events"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/sliceutils"
|
||||
"k8s.io/kubernetes/pkg/scheduler/algorithm"
|
||||
nodeutil "k8s.io/kubernetes/pkg/util/node"
|
||||
"k8s.io/kubernetes/pkg/version"
|
||||
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
|
||||
volutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -189,8 +189,8 @@ func (kl *Kubelet) updateDefaultLabels(initialNode, existingNode *v1.Node) bool
|
|||
// whether the existing node must be updated.
|
||||
func (kl *Kubelet) reconcileCMADAnnotationWithExistingNode(node, existingNode *v1.Node) bool {
|
||||
var (
|
||||
existingCMAAnnotation = existingNode.Annotations[volumehelper.ControllerManagedAttachAnnotation]
|
||||
newCMAAnnotation, newSet = node.Annotations[volumehelper.ControllerManagedAttachAnnotation]
|
||||
existingCMAAnnotation = existingNode.Annotations[volutil.ControllerManagedAttachAnnotation]
|
||||
newCMAAnnotation, newSet = node.Annotations[volutil.ControllerManagedAttachAnnotation]
|
||||
)
|
||||
|
||||
if newCMAAnnotation == existingCMAAnnotation {
|
||||
|
|
@ -202,13 +202,13 @@ func (kl *Kubelet) reconcileCMADAnnotationWithExistingNode(node, existingNode *v
|
|||
// the correct value of the annotation.
|
||||
if !newSet {
|
||||
glog.Info("Controller attach-detach setting changed to false; updating existing Node")
|
||||
delete(existingNode.Annotations, volumehelper.ControllerManagedAttachAnnotation)
|
||||
delete(existingNode.Annotations, volutil.ControllerManagedAttachAnnotation)
|
||||
} else {
|
||||
glog.Info("Controller attach-detach setting changed to true; updating existing Node")
|
||||
if existingNode.Annotations == nil {
|
||||
existingNode.Annotations = make(map[string]string)
|
||||
}
|
||||
existingNode.Annotations[volumehelper.ControllerManagedAttachAnnotation] = newCMAAnnotation
|
||||
existingNode.Annotations[volutil.ControllerManagedAttachAnnotation] = newCMAAnnotation
|
||||
}
|
||||
|
||||
return true
|
||||
|
|
@ -269,7 +269,7 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) {
|
|||
}
|
||||
|
||||
glog.Infof("Setting node annotation to enable volume controller attach/detach")
|
||||
node.Annotations[volumehelper.ControllerManagedAttachAnnotation] = "true"
|
||||
node.Annotations[volutil.ControllerManagedAttachAnnotation] = "true"
|
||||
} else {
|
||||
glog.Infof("Controller attach/detach is disabled for this node; Kubelet will attach and detach volumes")
|
||||
}
|
||||
|
|
@ -279,7 +279,7 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) {
|
|||
node.Annotations = make(map[string]string)
|
||||
}
|
||||
glog.Infof("Setting node annotation to keep pod volumes of terminated pods attached to the node")
|
||||
node.Annotations[volumehelper.KeepTerminatedPodVolumesAnnotation] = "true"
|
||||
node.Annotations[volutil.KeepTerminatedPodVolumesAnnotation] = "true"
|
||||
}
|
||||
|
||||
// @question: should this be place after the call to the cloud provider? which also applies labels
|
||||
|
|
@ -303,7 +303,7 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) {
|
|||
// TODO(roberthbailey): Can we do this without having credentials to talk
|
||||
// to the cloud provider?
|
||||
// TODO: ExternalID is deprecated, we'll have to drop this code
|
||||
externalID, err := instances.ExternalID(kl.nodeName)
|
||||
externalID, err := instances.ExternalID(context.TODO(), kl.nodeName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get external ID from cloud provider: %v", err)
|
||||
}
|
||||
|
|
@ -313,13 +313,13 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) {
|
|||
// cloudprovider from arbitrary nodes. At most, we should talk to a
|
||||
// local metadata server here.
|
||||
if node.Spec.ProviderID == "" {
|
||||
node.Spec.ProviderID, err = cloudprovider.GetInstanceProviderID(kl.cloud, kl.nodeName)
|
||||
node.Spec.ProviderID, err = cloudprovider.GetInstanceProviderID(context.TODO(), kl.cloud, kl.nodeName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
instanceType, err := instances.InstanceType(kl.nodeName)
|
||||
instanceType, err := instances.InstanceType(context.TODO(), kl.nodeName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -330,7 +330,7 @@ func (kl *Kubelet) initialNode() (*v1.Node, error) {
|
|||
// If the cloud has zone information, label the node with the zone information
|
||||
zones, ok := kl.cloud.Zones()
|
||||
if ok {
|
||||
zone, err := zones.GetZone()
|
||||
zone, err := zones.GetZone(context.TODO())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get zone from cloud provider: %v", err)
|
||||
}
|
||||
|
|
@ -453,7 +453,7 @@ func (kl *Kubelet) setNodeAddress(node *v1.Node) error {
|
|||
// to the cloud provider?
|
||||
// TODO(justinsb): We can if CurrentNodeName() was actually CurrentNode() and returned an interface
|
||||
// TODO: If IP addresses couldn't be fetched from the cloud provider, should kubelet fallback on the other methods for getting the IP below?
|
||||
nodeAddresses, err := instances.NodeAddresses(kl.nodeName)
|
||||
nodeAddresses, err := instances.NodeAddresses(context.TODO(), kl.nodeName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get node address from cloud provider: %v", err)
|
||||
}
|
||||
|
|
@ -548,6 +548,10 @@ func (kl *Kubelet) setNodeStatusMachineInfo(node *v1.Node) {
|
|||
}
|
||||
}
|
||||
|
||||
var devicePluginAllocatable v1.ResourceList
|
||||
var devicePluginCapacity v1.ResourceList
|
||||
var removedDevicePlugins []string
|
||||
|
||||
// TODO: Post NotReady if we cannot get MachineInfo from cAdvisor. This needs to start
|
||||
// cAdvisor locally, e.g. for test-cmd.sh, and in integration test.
|
||||
info, err := kl.GetCachedMachineInfo()
|
||||
|
|
@ -592,16 +596,25 @@ func (kl *Kubelet) setNodeStatusMachineInfo(node *v1.Node) {
|
|||
}
|
||||
}
|
||||
|
||||
devicePluginCapacity, removedDevicePlugins := kl.containerManager.GetDevicePluginResourceCapacity()
|
||||
devicePluginCapacity, devicePluginAllocatable, removedDevicePlugins = kl.containerManager.GetDevicePluginResourceCapacity()
|
||||
if devicePluginCapacity != nil {
|
||||
for k, v := range devicePluginCapacity {
|
||||
glog.V(2).Infof("Update capacity for %s to %d", k, v.Value())
|
||||
node.Status.Capacity[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
for _, removedResource := range removedDevicePlugins {
|
||||
glog.V(2).Infof("Remove capacity for %s", removedResource)
|
||||
delete(node.Status.Capacity, v1.ResourceName(removedResource))
|
||||
glog.V(2).Infof("Set capacity for %s to 0 on device removal", removedResource)
|
||||
// Set the capacity of the removed resource to 0 instead of
|
||||
// removing the resource from the node status. This is to indicate
|
||||
// that the resource is managed by device plugin and had been
|
||||
// registered before.
|
||||
//
|
||||
// This is required to differentiate the device plugin managed
|
||||
// resources and the cluster-level resources, which are absent in
|
||||
// node status.
|
||||
node.Status.Capacity[v1.ResourceName(removedResource)] = *resource.NewQuantity(int64(0), resource.DecimalSI)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -629,6 +642,12 @@ func (kl *Kubelet) setNodeStatusMachineInfo(node *v1.Node) {
|
|||
}
|
||||
node.Status.Allocatable[k] = value
|
||||
}
|
||||
if devicePluginAllocatable != nil {
|
||||
for k, v := range devicePluginAllocatable {
|
||||
glog.V(2).Infof("Update allocatable for %s to %d", k, v.Value())
|
||||
node.Status.Allocatable[k] = v
|
||||
}
|
||||
}
|
||||
// for every huge page reservation, we need to remove it from allocatable memory
|
||||
for k, v := range node.Status.Capacity {
|
||||
if v1helper.IsHugePageResourceName(k) {
|
||||
|
|
@ -682,7 +701,6 @@ func (kl *Kubelet) setNodeStatusImages(node *v1.Node) {
|
|||
return
|
||||
}
|
||||
// sort the images from max to min, and only set top N images into the node status.
|
||||
sort.Sort(sliceutils.ByImageSize(containerImages))
|
||||
if maxImagesInNodeStatus < len(containerImages) {
|
||||
containerImages = containerImages[0:maxImagesInNodeStatus]
|
||||
}
|
||||
|
|
@ -723,17 +741,28 @@ func (kl *Kubelet) setNodeReadyCondition(node *v1.Node) {
|
|||
// This is due to an issue with version skewed kubelet and master components.
|
||||
// ref: https://github.com/kubernetes/kubernetes/issues/16961
|
||||
currentTime := metav1.NewTime(kl.clock.Now())
|
||||
var newNodeReadyCondition v1.NodeCondition
|
||||
newNodeReadyCondition := v1.NodeCondition{
|
||||
Type: v1.NodeReady,
|
||||
Status: v1.ConditionTrue,
|
||||
Reason: "KubeletReady",
|
||||
Message: "kubelet is posting ready status",
|
||||
LastHeartbeatTime: currentTime,
|
||||
}
|
||||
rs := append(kl.runtimeState.runtimeErrors(), kl.runtimeState.networkErrors()...)
|
||||
if len(rs) == 0 {
|
||||
newNodeReadyCondition = v1.NodeCondition{
|
||||
Type: v1.NodeReady,
|
||||
Status: v1.ConditionTrue,
|
||||
Reason: "KubeletReady",
|
||||
Message: "kubelet is posting ready status",
|
||||
LastHeartbeatTime: currentTime,
|
||||
requiredCapacities := []v1.ResourceName{v1.ResourceCPU, v1.ResourceMemory, v1.ResourcePods}
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.LocalStorageCapacityIsolation) {
|
||||
requiredCapacities = append(requiredCapacities, v1.ResourceEphemeralStorage)
|
||||
}
|
||||
missingCapacities := []string{}
|
||||
for _, resource := range requiredCapacities {
|
||||
if _, found := node.Status.Capacity[resource]; !found {
|
||||
missingCapacities = append(missingCapacities, string(resource))
|
||||
}
|
||||
} else {
|
||||
}
|
||||
if len(missingCapacities) > 0 {
|
||||
rs = append(rs, fmt.Sprintf("Missing node capacity for resources: %s", strings.Join(missingCapacities, ", ")))
|
||||
}
|
||||
if len(rs) > 0 {
|
||||
newNodeReadyCondition = v1.NodeCondition{
|
||||
Type: v1.NodeReady,
|
||||
Status: v1.ConditionFalse,
|
||||
|
|
@ -742,7 +771,6 @@ func (kl *Kubelet) setNodeReadyCondition(node *v1.Node) {
|
|||
LastHeartbeatTime: currentTime,
|
||||
}
|
||||
}
|
||||
|
||||
// Append AppArmor status if it's enabled.
|
||||
// TODO(tallclair): This is a temporary message until node feature reporting is added.
|
||||
if newNodeReadyCondition.Status == v1.ConditionTrue &&
|
||||
|
|
@ -841,6 +869,62 @@ func (kl *Kubelet) setNodeMemoryPressureCondition(node *v1.Node) {
|
|||
}
|
||||
}
|
||||
|
||||
// setNodePIDPressureCondition for the node.
|
||||
// TODO: this needs to move somewhere centralized...
|
||||
func (kl *Kubelet) setNodePIDPressureCondition(node *v1.Node) {
|
||||
currentTime := metav1.NewTime(kl.clock.Now())
|
||||
var condition *v1.NodeCondition
|
||||
|
||||
// Check if NodePIDPressure condition already exists and if it does, just pick it up for update.
|
||||
for i := range node.Status.Conditions {
|
||||
if node.Status.Conditions[i].Type == v1.NodePIDPressure {
|
||||
condition = &node.Status.Conditions[i]
|
||||
}
|
||||
}
|
||||
|
||||
newCondition := false
|
||||
// If the NodePIDPressure condition doesn't exist, create one
|
||||
if condition == nil {
|
||||
condition = &v1.NodeCondition{
|
||||
Type: v1.NodePIDPressure,
|
||||
Status: v1.ConditionUnknown,
|
||||
}
|
||||
// cannot be appended to node.Status.Conditions here because it gets
|
||||
// copied to the slice. So if we append to the slice here none of the
|
||||
// updates we make below are reflected in the slice.
|
||||
newCondition = true
|
||||
}
|
||||
|
||||
// Update the heartbeat time
|
||||
condition.LastHeartbeatTime = currentTime
|
||||
|
||||
// Note: The conditions below take care of the case when a new NodePIDPressure condition is
|
||||
// created and as well as the case when the condition already exists. When a new condition
|
||||
// is created its status is set to v1.ConditionUnknown which matches either
|
||||
// condition.Status != v1.ConditionTrue or
|
||||
// condition.Status != v1.ConditionFalse in the conditions below depending on whether
|
||||
// the kubelet is under PID pressure or not.
|
||||
if kl.evictionManager.IsUnderPIDPressure() {
|
||||
if condition.Status != v1.ConditionTrue {
|
||||
condition.Status = v1.ConditionTrue
|
||||
condition.Reason = "KubeletHasInsufficientPID"
|
||||
condition.Message = "kubelet has insufficient PID available"
|
||||
condition.LastTransitionTime = currentTime
|
||||
kl.recordNodeStatusEvent(v1.EventTypeNormal, "NodeHasInsufficientPID")
|
||||
}
|
||||
} else if condition.Status != v1.ConditionFalse {
|
||||
condition.Status = v1.ConditionFalse
|
||||
condition.Reason = "KubeletHasSufficientPID"
|
||||
condition.Message = "kubelet has sufficient PID available"
|
||||
condition.LastTransitionTime = currentTime
|
||||
kl.recordNodeStatusEvent(v1.EventTypeNormal, "NodeHasSufficientPID")
|
||||
}
|
||||
|
||||
if newCondition {
|
||||
node.Status.Conditions = append(node.Status.Conditions, *condition)
|
||||
}
|
||||
}
|
||||
|
||||
// setNodeDiskPressureCondition for the node.
|
||||
// TODO: this needs to move somewhere centralized...
|
||||
func (kl *Kubelet) setNodeDiskPressureCondition(node *v1.Node) {
|
||||
|
|
@ -932,10 +1016,15 @@ func (kl *Kubelet) setNodeOODCondition(node *v1.Node) {
|
|||
|
||||
// Maintains Node.Spec.Unschedulable value from previous run of tryUpdateNodeStatus()
|
||||
// TODO: why is this a package var?
|
||||
var oldNodeUnschedulable bool
|
||||
var (
|
||||
oldNodeUnschedulable bool
|
||||
oldNodeUnschedulableLock sync.Mutex
|
||||
)
|
||||
|
||||
// record if node schedulable change.
|
||||
func (kl *Kubelet) recordNodeSchedulableEvent(node *v1.Node) {
|
||||
oldNodeUnschedulableLock.Lock()
|
||||
defer oldNodeUnschedulableLock.Unlock()
|
||||
if oldNodeUnschedulable != node.Spec.Unschedulable {
|
||||
if node.Spec.Unschedulable {
|
||||
kl.recordNodeStatusEvent(v1.EventTypeNormal, events.NodeNotSchedulable)
|
||||
|
|
@ -983,6 +1072,7 @@ func (kl *Kubelet) defaultNodeStatusFuncs() []func(*v1.Node) error {
|
|||
withoutError(kl.setNodeOODCondition),
|
||||
withoutError(kl.setNodeMemoryPressureCondition),
|
||||
withoutError(kl.setNodeDiskPressureCondition),
|
||||
withoutError(kl.setNodePIDPressureCondition),
|
||||
withoutError(kl.setNodeReadyCondition),
|
||||
withoutError(kl.setNodeVolumesInUseStatus),
|
||||
withoutError(kl.recordNodeSchedulableEvent),
|
||||
|
|
|
|||
221
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status_test.go
generated
vendored
221
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_node_status_test.go
generated
vendored
|
|
@ -53,7 +53,7 @@ import (
|
|||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/sliceutils"
|
||||
"k8s.io/kubernetes/pkg/version"
|
||||
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
|
||||
"k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -96,7 +96,7 @@ func generateImageTags() []string {
|
|||
// that kubelet report up to maxNamesPerImageInNodeStatus tags.
|
||||
count := rand.IntnRange(maxNamesPerImageInNodeStatus+1, maxImageTagsForTest+1)
|
||||
for ; count > 0; count-- {
|
||||
tagList = append(tagList, "gcr.io/google_containers:v"+strconv.Itoa(count))
|
||||
tagList = append(tagList, "k8s.gcr.io:v"+strconv.Itoa(count))
|
||||
}
|
||||
return tagList
|
||||
}
|
||||
|
|
@ -120,12 +120,12 @@ func applyNodeStatusPatch(originalNode *v1.Node, patch []byte) (*v1.Node, error)
|
|||
|
||||
type localCM struct {
|
||||
cm.ContainerManager
|
||||
allocatable v1.ResourceList
|
||||
capacity v1.ResourceList
|
||||
allocatableReservation v1.ResourceList
|
||||
capacity v1.ResourceList
|
||||
}
|
||||
|
||||
func (lcm *localCM) GetNodeAllocatableReservation() v1.ResourceList {
|
||||
return lcm.allocatable
|
||||
return lcm.allocatableReservation
|
||||
}
|
||||
|
||||
func (lcm *localCM) GetCapacity() v1.ResourceList {
|
||||
|
|
@ -222,13 +222,15 @@ func TestUpdateNewNodeStatus(t *testing.T) {
|
|||
kubelet.kubeClient = nil // ensure only the heartbeat client is used
|
||||
kubelet.containerManager = &localCM{
|
||||
ContainerManager: cm.NewStubContainerManager(),
|
||||
allocatable: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(200, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(100E6, resource.BinarySI),
|
||||
allocatableReservation: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(200, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(100E6, resource.BinarySI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(2000, resource.BinarySI),
|
||||
},
|
||||
capacity: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(5000, resource.BinarySI),
|
||||
},
|
||||
}
|
||||
kubeClient := testKubelet.fakeKubeClient
|
||||
|
|
@ -248,7 +250,21 @@ func TestUpdateNewNodeStatus(t *testing.T) {
|
|||
KernelVersion: "3.16.0-0.bpo.4-amd64",
|
||||
ContainerOsVersion: "Debian GNU/Linux 7 (wheezy)",
|
||||
}
|
||||
mockCadvisor.On("ImagesFsInfo").Return(cadvisorapiv2.FsInfo{
|
||||
Usage: 400,
|
||||
Capacity: 5000,
|
||||
Available: 600,
|
||||
}, nil)
|
||||
mockCadvisor.On("RootFsInfo").Return(cadvisorapiv2.FsInfo{
|
||||
Usage: 400,
|
||||
Capacity: 5000,
|
||||
Available: 600,
|
||||
}, nil)
|
||||
mockCadvisor.On("VersionInfo").Return(versionInfo, nil)
|
||||
maxAge := 0 * time.Second
|
||||
options := cadvisorapiv2.RequestOptions{IdType: cadvisorapiv2.TypeName, Count: 2, Recursive: false, MaxAge: &maxAge}
|
||||
mockCadvisor.On("ContainerInfoV2", "/", options).Return(map[string]cadvisorapiv2.ContainerInfo{}, nil)
|
||||
kubelet.machineInfo = machineInfo
|
||||
|
||||
expectedNode := &v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: testKubeletHostname},
|
||||
|
|
@ -279,6 +295,14 @@ func TestUpdateNewNodeStatus(t *testing.T) {
|
|||
LastHeartbeatTime: metav1.Time{},
|
||||
LastTransitionTime: metav1.Time{},
|
||||
},
|
||||
{
|
||||
Type: v1.NodePIDPressure,
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: "KubeletHasSufficientPID",
|
||||
Message: fmt.Sprintf("kubelet has sufficient PID available"),
|
||||
LastHeartbeatTime: metav1.Time{},
|
||||
LastTransitionTime: metav1.Time{},
|
||||
},
|
||||
{
|
||||
Type: v1.NodeReady,
|
||||
Status: v1.ConditionTrue,
|
||||
|
|
@ -301,14 +325,16 @@ func TestUpdateNewNodeStatus(t *testing.T) {
|
|||
KubeProxyVersion: version.Get().String(),
|
||||
},
|
||||
Capacity: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(5000, resource.BinarySI),
|
||||
},
|
||||
Allocatable: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(1800, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(9900E6, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(1800, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(9900E6, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(3000, resource.BinarySI),
|
||||
},
|
||||
Addresses: []v1.NodeAddress{
|
||||
{Type: v1.NodeInternalIP, Address: "127.0.0.1"},
|
||||
|
|
@ -335,7 +361,8 @@ func TestUpdateNewNodeStatus(t *testing.T) {
|
|||
}
|
||||
|
||||
// Version skew workaround. See: https://github.com/kubernetes/kubernetes/issues/16961
|
||||
assert.Equal(t, v1.NodeReady, updatedNode.Status.Conditions[len(updatedNode.Status.Conditions)-1].Type, "NotReady should be last")
|
||||
assert.Equal(t, v1.NodeReady, updatedNode.Status.Conditions[len(updatedNode.Status.Conditions)-1].Type,
|
||||
"NotReady should be last")
|
||||
assert.Len(t, updatedNode.Status.Images, maxImagesInNodeStatus)
|
||||
assert.True(t, apiequality.Semantic.DeepEqual(expectedNode, updatedNode), "%s", diff.ObjectDiff(expectedNode, updatedNode))
|
||||
}
|
||||
|
|
@ -347,13 +374,14 @@ func TestUpdateExistingNodeStatus(t *testing.T) {
|
|||
kubelet.kubeClient = nil // ensure only the heartbeat client is used
|
||||
kubelet.containerManager = &localCM{
|
||||
ContainerManager: cm.NewStubContainerManager(),
|
||||
allocatable: v1.ResourceList{
|
||||
allocatableReservation: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(200, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(100E6, resource.BinarySI),
|
||||
},
|
||||
capacity: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(20E9, resource.BinarySI),
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(20E9, resource.BinarySI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(5000, resource.BinarySI),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -387,6 +415,14 @@ func TestUpdateExistingNodeStatus(t *testing.T) {
|
|||
LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
LastTransitionTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
{
|
||||
Type: v1.NodePIDPressure,
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: "KubeletHasSufficientPID",
|
||||
Message: fmt.Sprintf("kubelet has sufficient PID available"),
|
||||
LastHeartbeatTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
LastTransitionTime: metav1.Date(2012, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||
},
|
||||
{
|
||||
Type: v1.NodeReady,
|
||||
Status: v1.ConditionTrue,
|
||||
|
|
@ -423,7 +459,21 @@ func TestUpdateExistingNodeStatus(t *testing.T) {
|
|||
KernelVersion: "3.16.0-0.bpo.4-amd64",
|
||||
ContainerOsVersion: "Debian GNU/Linux 7 (wheezy)",
|
||||
}
|
||||
mockCadvisor.On("ImagesFsInfo").Return(cadvisorapiv2.FsInfo{
|
||||
Usage: 400,
|
||||
Capacity: 5000,
|
||||
Available: 600,
|
||||
}, nil)
|
||||
mockCadvisor.On("RootFsInfo").Return(cadvisorapiv2.FsInfo{
|
||||
Usage: 400,
|
||||
Capacity: 5000,
|
||||
Available: 600,
|
||||
}, nil)
|
||||
mockCadvisor.On("VersionInfo").Return(versionInfo, nil)
|
||||
maxAge := 0 * time.Second
|
||||
options := cadvisorapiv2.RequestOptions{IdType: cadvisorapiv2.TypeName, Count: 2, Recursive: false, MaxAge: &maxAge}
|
||||
mockCadvisor.On("ContainerInfoV2", "/", options).Return(map[string]cadvisorapiv2.ContainerInfo{}, nil)
|
||||
kubelet.machineInfo = machineInfo
|
||||
|
||||
expectedNode := &v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: testKubeletHostname},
|
||||
|
|
@ -454,6 +504,14 @@ func TestUpdateExistingNodeStatus(t *testing.T) {
|
|||
LastHeartbeatTime: metav1.Time{},
|
||||
LastTransitionTime: metav1.Time{},
|
||||
},
|
||||
{
|
||||
Type: v1.NodePIDPressure,
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: "KubeletHasSufficientPID",
|
||||
Message: fmt.Sprintf("kubelet has sufficient PID available"),
|
||||
LastHeartbeatTime: metav1.Time{},
|
||||
LastTransitionTime: metav1.Time{},
|
||||
},
|
||||
{
|
||||
Type: v1.NodeReady,
|
||||
Status: v1.ConditionTrue,
|
||||
|
|
@ -476,14 +534,16 @@ func TestUpdateExistingNodeStatus(t *testing.T) {
|
|||
KubeProxyVersion: version.Get().String(),
|
||||
},
|
||||
Capacity: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(20E9, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(20E9, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(5000, resource.BinarySI),
|
||||
},
|
||||
Allocatable: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(1800, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(19900E6, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(1800, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(19900E6, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(5000, resource.BinarySI),
|
||||
},
|
||||
Addresses: []v1.NodeAddress{
|
||||
{Type: v1.NodeInternalIP, Address: "127.0.0.1"},
|
||||
|
|
@ -492,12 +552,12 @@ func TestUpdateExistingNodeStatus(t *testing.T) {
|
|||
// images will be sorted from max to min in node status.
|
||||
Images: []v1.ContainerImage{
|
||||
{
|
||||
Names: []string{"gcr.io/google_containers:v3", "gcr.io/google_containers:v4"},
|
||||
SizeBytes: 456,
|
||||
Names: []string{"k8s.gcr.io:v1", "k8s.gcr.io:v2"},
|
||||
SizeBytes: 123,
|
||||
},
|
||||
{
|
||||
Names: []string{"gcr.io/google_containers:v1", "gcr.io/google_containers:v2"},
|
||||
SizeBytes: 123,
|
||||
Names: []string{"k8s.gcr.io:v3", "k8s.gcr.io:v4"},
|
||||
SizeBytes: 456,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -565,7 +625,7 @@ func TestUpdateExistingNodeStatusTimeout(t *testing.T) {
|
|||
kubelet.heartbeatClient, err = v1core.NewForConfig(config)
|
||||
kubelet.containerManager = &localCM{
|
||||
ContainerManager: cm.NewStubContainerManager(),
|
||||
allocatable: v1.ResourceList{
|
||||
allocatableReservation: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(200, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(100E6, resource.BinarySI),
|
||||
},
|
||||
|
|
@ -591,13 +651,15 @@ func TestUpdateNodeStatusWithRuntimeStateError(t *testing.T) {
|
|||
kubelet.kubeClient = nil // ensure only the heartbeat client is used
|
||||
kubelet.containerManager = &localCM{
|
||||
ContainerManager: cm.NewStubContainerManager(),
|
||||
allocatable: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(200, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(100E6, resource.BinarySI),
|
||||
allocatableReservation: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(200, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(100E6, resource.BinarySI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
},
|
||||
capacity: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(20E9, resource.BinarySI),
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -619,7 +681,21 @@ func TestUpdateNodeStatusWithRuntimeStateError(t *testing.T) {
|
|||
KernelVersion: "3.16.0-0.bpo.4-amd64",
|
||||
ContainerOsVersion: "Debian GNU/Linux 7 (wheezy)",
|
||||
}
|
||||
|
||||
mockCadvisor.On("VersionInfo").Return(versionInfo, nil)
|
||||
maxAge := 0 * time.Second
|
||||
options := cadvisorapiv2.RequestOptions{IdType: cadvisorapiv2.TypeName, Count: 2, Recursive: false, MaxAge: &maxAge}
|
||||
mockCadvisor.On("ContainerInfoV2", "/", options).Return(map[string]cadvisorapiv2.ContainerInfo{}, nil)
|
||||
mockCadvisor.On("ImagesFsInfo").Return(cadvisorapiv2.FsInfo{
|
||||
Usage: 400,
|
||||
Capacity: 10E9,
|
||||
}, nil)
|
||||
mockCadvisor.On("RootFsInfo").Return(cadvisorapiv2.FsInfo{
|
||||
Usage: 400,
|
||||
Capacity: 20E9,
|
||||
}, nil)
|
||||
|
||||
kubelet.machineInfo = machineInfo
|
||||
|
||||
expectedNode := &v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: testKubeletHostname},
|
||||
|
|
@ -650,6 +726,14 @@ func TestUpdateNodeStatusWithRuntimeStateError(t *testing.T) {
|
|||
LastHeartbeatTime: metav1.Time{},
|
||||
LastTransitionTime: metav1.Time{},
|
||||
},
|
||||
{
|
||||
Type: v1.NodePIDPressure,
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: "KubeletHasSufficientPID",
|
||||
Message: fmt.Sprintf("kubelet has sufficient PID available"),
|
||||
LastHeartbeatTime: metav1.Time{},
|
||||
LastTransitionTime: metav1.Time{},
|
||||
},
|
||||
{}, //placeholder
|
||||
},
|
||||
NodeInfo: v1.NodeSystemInfo{
|
||||
|
|
@ -665,14 +749,16 @@ func TestUpdateNodeStatusWithRuntimeStateError(t *testing.T) {
|
|||
KubeProxyVersion: version.Get().String(),
|
||||
},
|
||||
Capacity: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(20E9, resource.BinarySI),
|
||||
},
|
||||
Allocatable: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(1800, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(9900E6, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(1800, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(9900E6, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
},
|
||||
Addresses: []v1.NodeAddress{
|
||||
{Type: v1.NodeInternalIP, Address: "127.0.0.1"},
|
||||
|
|
@ -680,12 +766,12 @@ func TestUpdateNodeStatusWithRuntimeStateError(t *testing.T) {
|
|||
},
|
||||
Images: []v1.ContainerImage{
|
||||
{
|
||||
Names: []string{"gcr.io/google_containers:v3", "gcr.io/google_containers:v4"},
|
||||
SizeBytes: 456,
|
||||
Names: []string{"k8s.gcr.io:v1", "k8s.gcr.io:v2"},
|
||||
SizeBytes: 123,
|
||||
},
|
||||
{
|
||||
Names: []string{"gcr.io/google_containers:v1", "gcr.io/google_containers:v2"},
|
||||
SizeBytes: 123,
|
||||
Names: []string{"k8s.gcr.io:v3", "k8s.gcr.io:v4"},
|
||||
SizeBytes: 456,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -856,6 +942,7 @@ func TestRegisterWithApiServer(t *testing.T) {
|
|||
Usage: 9,
|
||||
Capacity: 10,
|
||||
}, nil)
|
||||
kubelet.machineInfo = machineInfo
|
||||
|
||||
done := make(chan struct{})
|
||||
go func() {
|
||||
|
|
@ -895,7 +982,7 @@ func TestTryRegisterWithApiServer(t *testing.T) {
|
|||
|
||||
if cmad {
|
||||
node.Annotations = make(map[string]string)
|
||||
node.Annotations[volumehelper.ControllerManagedAttachAnnotation] = "true"
|
||||
node.Annotations[util.ControllerManagedAttachAnnotation] = "true"
|
||||
}
|
||||
|
||||
return node
|
||||
|
|
@ -1047,7 +1134,7 @@ func TestTryRegisterWithApiServer(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
actualCMAD, _ := strconv.ParseBool(savedNode.Annotations[volumehelper.ControllerManagedAttachAnnotation])
|
||||
actualCMAD, _ := strconv.ParseBool(savedNode.Annotations[util.ControllerManagedAttachAnnotation])
|
||||
assert.Equal(t, tc.savedNodeCMAD, actualCMAD, "test [%s]", tc.name)
|
||||
}
|
||||
}
|
||||
|
|
@ -1063,12 +1150,14 @@ func TestUpdateNewNodeStatusTooLargeReservation(t *testing.T) {
|
|||
kubelet.kubeClient = nil // ensure only the heartbeat client is used
|
||||
kubelet.containerManager = &localCM{
|
||||
ContainerManager: cm.NewStubContainerManager(),
|
||||
allocatable: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(40000, resource.DecimalSI),
|
||||
allocatableReservation: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(40000, resource.DecimalSI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(1000, resource.BinarySI),
|
||||
},
|
||||
capacity: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(3000, resource.BinarySI),
|
||||
},
|
||||
}
|
||||
kubeClient := testKubelet.fakeKubeClient
|
||||
|
|
@ -1089,20 +1178,36 @@ func TestUpdateNewNodeStatusTooLargeReservation(t *testing.T) {
|
|||
ContainerOsVersion: "Debian GNU/Linux 7 (wheezy)",
|
||||
}
|
||||
mockCadvisor.On("VersionInfo").Return(versionInfo, nil)
|
||||
maxAge := 0 * time.Second
|
||||
options := cadvisorapiv2.RequestOptions{IdType: cadvisorapiv2.TypeName, Count: 2, Recursive: false, MaxAge: &maxAge}
|
||||
mockCadvisor.On("ContainerInfoV2", "/", options).Return(map[string]cadvisorapiv2.ContainerInfo{}, nil)
|
||||
mockCadvisor.On("ImagesFsInfo").Return(cadvisorapiv2.FsInfo{
|
||||
Usage: 400,
|
||||
Capacity: 3000,
|
||||
Available: 600,
|
||||
}, nil)
|
||||
mockCadvisor.On("RootFsInfo").Return(cadvisorapiv2.FsInfo{
|
||||
Usage: 400,
|
||||
Capacity: 3000,
|
||||
Available: 600,
|
||||
}, nil)
|
||||
kubelet.machineInfo = machineInfo
|
||||
|
||||
expectedNode := &v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: testKubeletHostname},
|
||||
Spec: v1.NodeSpec{},
|
||||
Status: v1.NodeStatus{
|
||||
Capacity: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(2000, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(3000, resource.BinarySI),
|
||||
},
|
||||
Allocatable: v1.ResourceList{
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceCPU: *resource.NewMilliQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceMemory: *resource.NewQuantity(10E9, resource.BinarySI),
|
||||
v1.ResourcePods: *resource.NewQuantity(0, resource.DecimalSI),
|
||||
v1.ResourceEphemeralStorage: *resource.NewQuantity(2000, resource.BinarySI),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
135
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods.go
generated
vendored
135
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods.go
generated
vendored
|
|
@ -49,7 +49,7 @@ import (
|
|||
v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/fieldpath"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
"k8s.io/kubernetes/pkg/kubelet/cm"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
"k8s.io/kubernetes/pkg/kubelet/envvars"
|
||||
|
|
@ -61,9 +61,9 @@ import (
|
|||
kubetypes "k8s.io/kubernetes/pkg/kubelet/types"
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
||||
utilfile "k8s.io/kubernetes/pkg/util/file"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
mountutil "k8s.io/kubernetes/pkg/util/mount"
|
||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
|
||||
"k8s.io/kubernetes/pkg/volume/util/volumepathhandler"
|
||||
volumevalidation "k8s.io/kubernetes/pkg/volume/validation"
|
||||
"k8s.io/kubernetes/third_party/forked/golang/expansion"
|
||||
)
|
||||
|
|
@ -129,7 +129,7 @@ func makeAbsolutePath(goos, path string) string {
|
|||
|
||||
// makeBlockVolumes maps the raw block devices specified in the path of the container
|
||||
// Experimental
|
||||
func (kl *Kubelet) makeBlockVolumes(pod *v1.Pod, container *v1.Container, podVolumes kubecontainer.VolumeMap, blkutil volumeutil.BlockVolumePathHandler) ([]kubecontainer.DeviceInfo, error) {
|
||||
func (kl *Kubelet) makeBlockVolumes(pod *v1.Pod, container *v1.Container, podVolumes kubecontainer.VolumeMap, blkutil volumepathhandler.BlockVolumePathHandler) ([]kubecontainer.DeviceInfo, error) {
|
||||
var devices []kubecontainer.DeviceInfo
|
||||
for _, device := range container.VolumeDevices {
|
||||
// check path is absolute
|
||||
|
|
@ -161,7 +161,7 @@ func (kl *Kubelet) makeBlockVolumes(pod *v1.Pod, container *v1.Container, podVol
|
|||
}
|
||||
|
||||
// makeMounts determines the mount points for the given container.
|
||||
func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain, podIP string, podVolumes kubecontainer.VolumeMap) ([]kubecontainer.Mount, error) {
|
||||
func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain, podIP string, podVolumes kubecontainer.VolumeMap, mounter mountutil.Interface) ([]kubecontainer.Mount, func(), error) {
|
||||
// Kubernetes only mounts on /etc/hosts if:
|
||||
// - container is not an infrastructure (pause) container
|
||||
// - container is not already mounting on /etc/hosts
|
||||
|
|
@ -171,13 +171,14 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
|
|||
mountEtcHostsFile := len(podIP) > 0 && runtime.GOOS != "windows"
|
||||
glog.V(3).Infof("container: %v/%v/%v podIP: %q creating hosts mount: %v", pod.Namespace, pod.Name, container.Name, podIP, mountEtcHostsFile)
|
||||
mounts := []kubecontainer.Mount{}
|
||||
for _, mount := range container.VolumeMounts {
|
||||
var cleanupAction func() = nil
|
||||
for i, mount := range container.VolumeMounts {
|
||||
// do not mount /etc/hosts if container is already mounting on the path
|
||||
mountEtcHostsFile = mountEtcHostsFile && (mount.MountPath != etcHostsPath)
|
||||
vol, ok := podVolumes[mount.Name]
|
||||
if !ok || vol.Mounter == nil {
|
||||
glog.Errorf("Mount cannot be satisfied for container %q, because the volume is missing or the volume mounter is nil: %+v", container.Name, mount)
|
||||
return nil, fmt.Errorf("cannot find volume %q to mount into container %q", mount.Name, container.Name)
|
||||
return nil, cleanupAction, fmt.Errorf("cannot find volume %q to mount into container %q", mount.Name, container.Name)
|
||||
}
|
||||
|
||||
relabelVolume := false
|
||||
|
|
@ -188,27 +189,35 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
|
|||
vol.SELinuxLabeled = true
|
||||
relabelVolume = true
|
||||
}
|
||||
hostPath, err := volume.GetPath(vol.Mounter)
|
||||
hostPath, err := volumeutil.GetPath(vol.Mounter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, cleanupAction, err
|
||||
}
|
||||
if mount.SubPath != "" {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.VolumeSubpath) {
|
||||
return nil, cleanupAction, fmt.Errorf("volume subpaths are disabled")
|
||||
}
|
||||
|
||||
if filepath.IsAbs(mount.SubPath) {
|
||||
return nil, fmt.Errorf("error SubPath `%s` must not be an absolute path", mount.SubPath)
|
||||
return nil, cleanupAction, fmt.Errorf("error SubPath `%s` must not be an absolute path", mount.SubPath)
|
||||
}
|
||||
|
||||
err = volumevalidation.ValidatePathNoBacksteps(mount.SubPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to provision SubPath `%s`: %v", mount.SubPath, err)
|
||||
return nil, cleanupAction, fmt.Errorf("unable to provision SubPath `%s`: %v", mount.SubPath, err)
|
||||
}
|
||||
|
||||
fileinfo, err := os.Lstat(hostPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, cleanupAction, err
|
||||
}
|
||||
perm := fileinfo.Mode()
|
||||
|
||||
hostPath = filepath.Join(hostPath, mount.SubPath)
|
||||
volumePath, err := filepath.EvalSymlinks(hostPath)
|
||||
if err != nil {
|
||||
return nil, cleanupAction, err
|
||||
}
|
||||
hostPath = filepath.Join(volumePath, mount.SubPath)
|
||||
|
||||
if subPathExists, err := utilfile.FileOrSymlinkExists(hostPath); err != nil {
|
||||
glog.Errorf("Could not determine if subPath %s exists; will not attempt to change its permissions", hostPath)
|
||||
|
|
@ -217,17 +226,25 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
|
|||
// incorrect ownership and mode. For example, the sub path directory must have at least g+rwx
|
||||
// when the pod specifies an fsGroup, and if the directory is not created here, Docker will
|
||||
// later auto-create it with the incorrect mode 0750
|
||||
if err := os.MkdirAll(hostPath, perm); err != nil {
|
||||
glog.Errorf("failed to mkdir:%s", hostPath)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// chmod the sub path because umask may have prevented us from making the sub path with the same
|
||||
// permissions as the mounter path
|
||||
if err := os.Chmod(hostPath, perm); err != nil {
|
||||
return nil, err
|
||||
// Make extra care not to escape the volume!
|
||||
if err := mounter.SafeMakeDir(hostPath, volumePath, perm); err != nil {
|
||||
glog.Errorf("failed to mkdir %q: %v", hostPath, err)
|
||||
return nil, cleanupAction, err
|
||||
}
|
||||
}
|
||||
hostPath, cleanupAction, err = mounter.PrepareSafeSubpath(mountutil.Subpath{
|
||||
VolumeMountIndex: i,
|
||||
Path: hostPath,
|
||||
VolumeName: vol.InnerVolumeSpecName,
|
||||
VolumePath: volumePath,
|
||||
PodDir: podDir,
|
||||
ContainerName: container.Name,
|
||||
})
|
||||
if err != nil {
|
||||
// Don't pass detailed error back to the user because it could give information about host filesystem
|
||||
glog.Errorf("failed to prepare subPath for volumeMount %q of container %q: %v", mount.Name, container.Name, err)
|
||||
return nil, cleanupAction, fmt.Errorf("failed to prepare subPath for volumeMount %q of container %q", mount.Name, container.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Docker Volume Mounts fail on Windows if it is not of the form C:/
|
||||
|
|
@ -243,15 +260,17 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
|
|||
|
||||
propagation, err := translateMountPropagation(mount.MountPropagation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, cleanupAction, err
|
||||
}
|
||||
glog.V(5).Infof("Pod %q container %q mount %q has propagation %q", format.Pod(pod), container.Name, mount.Name, propagation)
|
||||
|
||||
mustMountRO := vol.Mounter.GetAttributes().ReadOnly && utilfeature.DefaultFeatureGate.Enabled(features.ReadOnlyAPIDataVolumes)
|
||||
|
||||
mounts = append(mounts, kubecontainer.Mount{
|
||||
Name: mount.Name,
|
||||
ContainerPath: containerPath,
|
||||
HostPath: hostPath,
|
||||
ReadOnly: mount.ReadOnly,
|
||||
ReadOnly: mount.ReadOnly || mustMountRO,
|
||||
SELinuxRelabel: relabelVolume,
|
||||
Propagation: propagation,
|
||||
})
|
||||
|
|
@ -260,16 +279,22 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
|
|||
hostAliases := pod.Spec.HostAliases
|
||||
hostsMount, err := makeHostsMount(podDir, podIP, hostName, hostDomain, hostAliases, pod.Spec.HostNetwork)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, cleanupAction, err
|
||||
}
|
||||
mounts = append(mounts, *hostsMount)
|
||||
}
|
||||
return mounts, nil
|
||||
return mounts, cleanupAction, nil
|
||||
}
|
||||
|
||||
// translateMountPropagation transforms v1.MountPropagationMode to
|
||||
// runtimeapi.MountPropagation.
|
||||
func translateMountPropagation(mountMode *v1.MountPropagationMode) (runtimeapi.MountPropagation, error) {
|
||||
if runtime.GOOS == "windows" {
|
||||
// Windows containers doesn't support mount propagation, use private for it.
|
||||
// Refer https://docs.docker.com/storage/bind-mounts/#configure-bind-propagation.
|
||||
return runtimeapi.MountPropagation_PROPAGATION_PRIVATE, nil
|
||||
}
|
||||
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.MountPropagation) {
|
||||
// mount propagation is disabled, use private as in the old versions
|
||||
return runtimeapi.MountPropagation_PROPAGATION_PRIVATE, nil
|
||||
|
|
@ -430,49 +455,49 @@ func (kl *Kubelet) GetPodCgroupParent(pod *v1.Pod) string {
|
|||
|
||||
// GenerateRunContainerOptions generates the RunContainerOptions, which can be used by
|
||||
// the container runtime to set parameters for launching a container.
|
||||
func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (*kubecontainer.RunContainerOptions, error) {
|
||||
func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (*kubecontainer.RunContainerOptions, func(), error) {
|
||||
opts, err := kl.containerManager.GetResources(pod, container)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
cgroupParent := kl.GetPodCgroupParent(pod)
|
||||
opts.CgroupParent = cgroupParent
|
||||
hostname, hostDomainName, err := kl.GeneratePodHostNameAndDomain(pod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
opts.Hostname = hostname
|
||||
podName := volumehelper.GetUniquePodName(pod)
|
||||
podName := volumeutil.GetUniquePodName(pod)
|
||||
volumes := kl.volumeManager.GetMountedVolumesForPod(podName)
|
||||
|
||||
opts.PortMappings = kubecontainer.MakePortMappings(container)
|
||||
// TODO(random-liu): Move following convert functions into pkg/kubelet/container
|
||||
devices, err := kl.makeGPUDevices(pod, container)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
opts.Devices = append(opts.Devices, devices...)
|
||||
|
||||
// TODO: remove feature gate check after no longer needed
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.BlockVolume) {
|
||||
blkutil := volumeutil.NewBlockVolumePathHandler()
|
||||
blkutil := volumepathhandler.NewBlockVolumePathHandler()
|
||||
blkVolumes, err := kl.makeBlockVolumes(pod, container, volumes, blkutil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
opts.Devices = append(opts.Devices, blkVolumes...)
|
||||
}
|
||||
|
||||
mounts, err := makeMounts(pod, kl.getPodDir(pod.UID), container, hostname, hostDomainName, podIP, volumes)
|
||||
mounts, cleanupAction, err := makeMounts(pod, kl.getPodDir(pod.UID), container, hostname, hostDomainName, podIP, volumes, kl.mounter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, cleanupAction, err
|
||||
}
|
||||
opts.Mounts = append(opts.Mounts, mounts...)
|
||||
|
||||
envs, err := kl.makeEnvironmentVariables(pod, container, podIP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, cleanupAction, err
|
||||
}
|
||||
opts.Envs = append(opts.Envs, envs...)
|
||||
|
||||
|
|
@ -492,7 +517,7 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Contai
|
|||
opts.EnableHostUserNamespace = kl.enableHostUserNamespace(pod)
|
||||
}
|
||||
|
||||
return opts, nil
|
||||
return opts, cleanupAction, nil
|
||||
}
|
||||
|
||||
var masterServices = sets.NewString("kubernetes")
|
||||
|
|
@ -1127,7 +1152,7 @@ func (kl *Kubelet) validateContainerLogStatus(podName string, podStatus *v1.PodS
|
|||
|
||||
switch {
|
||||
case previous:
|
||||
if lastState.Terminated == nil {
|
||||
if lastState.Terminated == nil || lastState.Terminated.ContainerID == "" {
|
||||
return kubecontainer.ContainerID{}, fmt.Errorf("previous terminated container %q in pod %q not found", containerName, podName)
|
||||
}
|
||||
cID = lastState.Terminated.ContainerID
|
||||
|
|
@ -1136,9 +1161,21 @@ func (kl *Kubelet) validateContainerLogStatus(podName string, podStatus *v1.PodS
|
|||
cID = cStatus.ContainerID
|
||||
|
||||
case terminated != nil:
|
||||
cID = terminated.ContainerID
|
||||
// in cases where the next container didn't start, terminated.ContainerID will be empty, so get logs from the lastState.Terminated.
|
||||
if terminated.ContainerID == "" {
|
||||
if lastState.Terminated != nil && lastState.Terminated.ContainerID != "" {
|
||||
cID = lastState.Terminated.ContainerID
|
||||
} else {
|
||||
return kubecontainer.ContainerID{}, fmt.Errorf("container %q in pod %q is terminated", containerName, podName)
|
||||
}
|
||||
} else {
|
||||
cID = terminated.ContainerID
|
||||
}
|
||||
|
||||
case lastState.Terminated != nil:
|
||||
if lastState.Terminated.ContainerID == "" {
|
||||
return kubecontainer.ContainerID{}, fmt.Errorf("container %q in pod %q is terminated", containerName, podName)
|
||||
}
|
||||
cID = lastState.Terminated.ContainerID
|
||||
|
||||
case waiting != nil:
|
||||
|
|
@ -1345,16 +1382,22 @@ func (kl *Kubelet) generateAPIPodStatus(pod *v1.Pod, podStatus *kubecontainer.Po
|
|||
spec := &pod.Spec
|
||||
allStatus := append(append([]v1.ContainerStatus{}, s.ContainerStatuses...), s.InitContainerStatuses...)
|
||||
s.Phase = getPhase(spec, allStatus)
|
||||
// Check for illegal phase transition
|
||||
if pod.Status.Phase == v1.PodFailed || pod.Status.Phase == v1.PodSucceeded {
|
||||
// API server shows terminal phase; transitions are not allowed
|
||||
if s.Phase != pod.Status.Phase {
|
||||
glog.Errorf("Pod attempted illegal phase transition from %s to %s: %v", pod.Status.Phase, s.Phase, s)
|
||||
// Force back to phase from the API server
|
||||
s.Phase = pod.Status.Phase
|
||||
}
|
||||
}
|
||||
kl.probeManager.UpdatePodStatus(pod.UID, s)
|
||||
s.Conditions = append(s.Conditions, status.GeneratePodInitializedCondition(spec, s.InitContainerStatuses, s.Phase))
|
||||
s.Conditions = append(s.Conditions, status.GeneratePodReadyCondition(spec, s.ContainerStatuses, s.Phase))
|
||||
// s (the PodStatus we are creating) will not have a PodScheduled condition yet, because converStatusToAPIStatus()
|
||||
// does not create one. If the existing PodStatus has a PodScheduled condition, then copy it into s and make sure
|
||||
// it is set to true. If the existing PodStatus does not have a PodScheduled condition, then create one that is set to true.
|
||||
if _, oldPodScheduled := podutil.GetPodCondition(&pod.Status, v1.PodScheduled); oldPodScheduled != nil {
|
||||
s.Conditions = append(s.Conditions, *oldPodScheduled)
|
||||
}
|
||||
podutil.UpdatePodCondition(&pod.Status, &v1.PodCondition{
|
||||
// Status manager will take care of the LastTransitionTimestamp, either preserve
|
||||
// the timestamp from apiserver, or set a new one. When kubelet sees the pod,
|
||||
// `PodScheduled` condition must be true.
|
||||
s.Conditions = append(s.Conditions, v1.PodCondition{
|
||||
Type: v1.PodScheduled,
|
||||
Status: v1.ConditionTrue,
|
||||
})
|
||||
|
|
|
|||
64
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods_test.go
generated
vendored
64
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods_test.go
generated
vendored
|
|
@ -42,11 +42,12 @@ import (
|
|||
// to "v1"?
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
_ "k8s.io/kubernetes/pkg/apis/core/install"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
containertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
|
||||
"k8s.io/kubernetes/pkg/kubelet/server/portforward"
|
||||
"k8s.io/kubernetes/pkg/kubelet/server/remotecommand"
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||
)
|
||||
|
||||
|
|
@ -303,6 +304,7 @@ func TestMakeMounts(t *testing.T) {
|
|||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
fm := &mount.FakeMounter{}
|
||||
pod := v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
HostNetwork: true,
|
||||
|
|
@ -315,7 +317,7 @@ func TestMakeMounts(t *testing.T) {
|
|||
return
|
||||
}
|
||||
|
||||
mounts, err := makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes)
|
||||
mounts, _, err := makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes, fm)
|
||||
|
||||
// validate only the error if we expect an error
|
||||
if tc.expectErr {
|
||||
|
|
@ -338,7 +340,7 @@ func TestMakeMounts(t *testing.T) {
|
|||
t.Errorf("Failed to enable feature gate for MountPropagation: %v", err)
|
||||
return
|
||||
}
|
||||
mounts, err = makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes)
|
||||
mounts, _, err = makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes, fm)
|
||||
if !tc.expectErr {
|
||||
expectedPrivateMounts := []kubecontainer.Mount{}
|
||||
for _, mount := range tc.expectedMounts {
|
||||
|
|
@ -353,6 +355,62 @@ func TestMakeMounts(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestDisabledSubpath(t *testing.T) {
|
||||
fm := &mount.FakeMounter{}
|
||||
pod := v1.Pod{
|
||||
Spec: v1.PodSpec{
|
||||
HostNetwork: true,
|
||||
},
|
||||
}
|
||||
podVolumes := kubecontainer.VolumeMap{
|
||||
"disk": kubecontainer.VolumeInfo{Mounter: &stubVolume{path: "/mnt/disk"}},
|
||||
}
|
||||
|
||||
cases := map[string]struct {
|
||||
container v1.Container
|
||||
expectError bool
|
||||
}{
|
||||
"subpath not specified": {
|
||||
v1.Container{
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
MountPath: "/mnt/path3",
|
||||
Name: "disk",
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
"subpath specified": {
|
||||
v1.Container{
|
||||
VolumeMounts: []v1.VolumeMount{
|
||||
{
|
||||
MountPath: "/mnt/path3",
|
||||
SubPath: "/must/not/be/absolute",
|
||||
Name: "disk",
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
true,
|
||||
},
|
||||
}
|
||||
|
||||
utilfeature.DefaultFeatureGate.Set("VolumeSubpath=false")
|
||||
defer utilfeature.DefaultFeatureGate.Set("VolumeSubpath=true")
|
||||
|
||||
for name, test := range cases {
|
||||
_, _, err := makeMounts(&pod, "/pod", &test.container, "fakepodname", "", "", podVolumes, fm)
|
||||
if err != nil && !test.expectError {
|
||||
t.Errorf("test %v failed: %v", name, err)
|
||||
}
|
||||
if err == nil && test.expectError {
|
||||
t.Errorf("test %v failed: expected error", name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMakeBlockVolumes(t *testing.T) {
|
||||
testKubelet := newTestKubelet(t, false /* controllerAttachDetachEnabled */)
|
||||
defer testKubelet.Cleanup()
|
||||
|
|
|
|||
4
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods_windows_test.go
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_pods_windows_test.go
generated
vendored
|
|
@ -24,6 +24,7 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/api/core/v1"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
)
|
||||
|
||||
func TestMakeMountsWindows(t *testing.T) {
|
||||
|
|
@ -64,7 +65,8 @@ func TestMakeMountsWindows(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
mounts, _ := makeMounts(&pod, "/pod", &container, "fakepodname", "", "", podVolumes)
|
||||
fm := &mount.FakeMounter{}
|
||||
mounts, _, _ := makeMounts(&pod, "/pod", &container, "fakepodname", "", "", podVolumes, fm)
|
||||
|
||||
expectedMounts := []kubecontainer.Mount{
|
||||
{
|
||||
|
|
|
|||
123
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_test.go
generated
vendored
123
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_test.go
generated
vendored
|
|
@ -52,6 +52,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubelet/gpu"
|
||||
"k8s.io/kubernetes/pkg/kubelet/images"
|
||||
"k8s.io/kubernetes/pkg/kubelet/lifecycle"
|
||||
"k8s.io/kubernetes/pkg/kubelet/logs"
|
||||
"k8s.io/kubernetes/pkg/kubelet/network"
|
||||
nettest "k8s.io/kubernetes/pkg/kubelet/network/testing"
|
||||
"k8s.io/kubernetes/pkg/kubelet/pleg"
|
||||
|
|
@ -72,7 +73,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/volume"
|
||||
_ "k8s.io/kubernetes/pkg/volume/host_path"
|
||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
|
||||
"k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
@ -127,12 +128,12 @@ func newTestKubelet(t *testing.T, controllerAttachDetachEnabled bool) *TestKubel
|
|||
imageList := []kubecontainer.Image{
|
||||
{
|
||||
ID: "abc",
|
||||
RepoTags: []string{"gcr.io/google_containers:v1", "gcr.io/google_containers:v2"},
|
||||
RepoTags: []string{"k8s.gcr.io:v1", "k8s.gcr.io:v2"},
|
||||
Size: 123,
|
||||
},
|
||||
{
|
||||
ID: "efg",
|
||||
RepoTags: []string{"gcr.io/google_containers:v3", "gcr.io/google_containers:v4"},
|
||||
RepoTags: []string{"k8s.gcr.io:v3", "k8s.gcr.io:v4"},
|
||||
Size: 456,
|
||||
},
|
||||
}
|
||||
|
|
@ -256,12 +257,22 @@ func newTestKubeletWithImageList(
|
|||
HighThresholdPercent: 90,
|
||||
LowThresholdPercent: 80,
|
||||
}
|
||||
imageGCManager, err := images.NewImageGCManager(fakeRuntime, kubelet.StatsProvider, fakeRecorder, fakeNodeRef, fakeImageGCPolicy)
|
||||
imageGCManager, err := images.NewImageGCManager(fakeRuntime, kubelet.StatsProvider, fakeRecorder, fakeNodeRef, fakeImageGCPolicy, "")
|
||||
assert.NoError(t, err)
|
||||
kubelet.imageManager = &fakeImageGCManager{
|
||||
fakeImageService: fakeRuntime,
|
||||
ImageGCManager: imageGCManager,
|
||||
}
|
||||
kubelet.containerLogManager = logs.NewStubContainerLogManager()
|
||||
containerGCPolicy := kubecontainer.ContainerGCPolicy{
|
||||
MinAge: time.Duration(0),
|
||||
MaxPerPodContainer: 1,
|
||||
MaxContainers: -1,
|
||||
}
|
||||
containerGC, err := kubecontainer.NewContainerGC(fakeRuntime, containerGCPolicy, kubelet.sourcesReady)
|
||||
assert.NoError(t, err)
|
||||
kubelet.containerGC = containerGC
|
||||
|
||||
fakeClock := clock.NewFakeClock(time.Now())
|
||||
kubelet.backOff = flowcontrol.NewBackOff(time.Second, time.Minute)
|
||||
kubelet.backOff.Clock = fakeClock
|
||||
|
|
@ -334,8 +345,6 @@ func newTestPods(count int) []*v1.Pod {
|
|||
return pods
|
||||
}
|
||||
|
||||
var emptyPodUIDs map[types.UID]kubetypes.SyncPodType
|
||||
|
||||
func TestSyncLoopAbort(t *testing.T) {
|
||||
testKubelet := newTestKubelet(t, false /* controllerAttachDetachEnabled */)
|
||||
defer testKubelet.Cleanup()
|
||||
|
|
@ -583,8 +592,10 @@ func TestHandlePluginResources(t *testing.T) {
|
|||
kl := testKubelet.kubelet
|
||||
|
||||
adjustedResource := v1.ResourceName("domain1.com/adjustedResource")
|
||||
unadjustedResouce := v1.ResourceName("domain2.com/unadjustedResouce")
|
||||
emptyResource := v1.ResourceName("domain2.com/emptyResource")
|
||||
missingResource := v1.ResourceName("domain2.com/missingResource")
|
||||
failedResource := v1.ResourceName("domain2.com/failedResource")
|
||||
resourceQuantity0 := *resource.NewQuantity(int64(0), resource.DecimalSI)
|
||||
resourceQuantity1 := *resource.NewQuantity(int64(1), resource.DecimalSI)
|
||||
resourceQuantity2 := *resource.NewQuantity(int64(2), resource.DecimalSI)
|
||||
resourceQuantityInvalid := *resource.NewQuantity(int64(-1), resource.DecimalSI)
|
||||
|
|
@ -592,9 +603,9 @@ func TestHandlePluginResources(t *testing.T) {
|
|||
nodes := []*v1.Node{
|
||||
{ObjectMeta: metav1.ObjectMeta{Name: testKubeletHostname},
|
||||
Status: v1.NodeStatus{Capacity: v1.ResourceList{}, Allocatable: v1.ResourceList{
|
||||
adjustedResource: resourceQuantity1,
|
||||
unadjustedResouce: resourceQuantity1,
|
||||
v1.ResourcePods: allowedPodQuantity,
|
||||
adjustedResource: resourceQuantity1,
|
||||
emptyResource: resourceQuantity0,
|
||||
v1.ResourcePods: allowedPodQuantity,
|
||||
}}},
|
||||
}
|
||||
kl.nodeInfo = testNodeInfo{nodes: nodes}
|
||||
|
|
@ -607,6 +618,7 @@ func TestHandlePluginResources(t *testing.T) {
|
|||
// quantity unchanged.
|
||||
updateResourceMap := map[v1.ResourceName]resource.Quantity{
|
||||
adjustedResource: resourceQuantity2,
|
||||
emptyResource: resourceQuantity0,
|
||||
failedResource: resourceQuantityInvalid,
|
||||
}
|
||||
pod := attrs.Pod
|
||||
|
|
@ -634,7 +646,7 @@ func TestHandlePluginResources(t *testing.T) {
|
|||
|
||||
// pod requiring adjustedResource can be successfully allocated because updatePluginResourcesFunc
|
||||
// adjusts node.allocatableResource for this resource to a sufficient value.
|
||||
fittingPodspec := v1.PodSpec{NodeName: string(kl.nodeName),
|
||||
fittingPodSpec := v1.PodSpec{NodeName: string(kl.nodeName),
|
||||
Containers: []v1.Container{{Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
adjustedResource: resourceQuantity2,
|
||||
|
|
@ -644,14 +656,30 @@ func TestHandlePluginResources(t *testing.T) {
|
|||
},
|
||||
}}},
|
||||
}
|
||||
// pod requiring unadjustedResouce with insufficient quantity will still fail PredicateAdmit.
|
||||
exceededPodSpec := v1.PodSpec{NodeName: string(kl.nodeName),
|
||||
// pod requiring emptyResource (extended resources with 0 allocatable) will
|
||||
// not pass PredicateAdmit.
|
||||
emptyPodSpec := v1.PodSpec{NodeName: string(kl.nodeName),
|
||||
Containers: []v1.Container{{Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
unadjustedResouce: resourceQuantity2,
|
||||
emptyResource: resourceQuantity2,
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
unadjustedResouce: resourceQuantity2,
|
||||
emptyResource: resourceQuantity2,
|
||||
},
|
||||
}}},
|
||||
}
|
||||
// pod requiring missingResource will pass PredicateAdmit.
|
||||
//
|
||||
// Extended resources missing in node status are ignored in PredicateAdmit.
|
||||
// This is required to support extended resources that are not managed by
|
||||
// device plugin, such as cluster-level resources.
|
||||
missingPodSpec := v1.PodSpec{NodeName: string(kl.nodeName),
|
||||
Containers: []v1.Container{{Resources: v1.ResourceRequirements{
|
||||
Limits: v1.ResourceList{
|
||||
missingResource: resourceQuantity2,
|
||||
},
|
||||
Requests: v1.ResourceList{
|
||||
missingResource: resourceQuantity2,
|
||||
},
|
||||
}}},
|
||||
}
|
||||
|
|
@ -666,21 +694,18 @@ func TestHandlePluginResources(t *testing.T) {
|
|||
},
|
||||
}}},
|
||||
}
|
||||
pods := []*v1.Pod{
|
||||
podWithUIDNameNsSpec("123", "fittingpod", "foo", fittingPodspec),
|
||||
podWithUIDNameNsSpec("456", "exceededpod", "foo", exceededPodSpec),
|
||||
podWithUIDNameNsSpec("789", "failedpod", "foo", failedPodSpec),
|
||||
}
|
||||
// The latter two pod should be rejected.
|
||||
fittingPod := pods[0]
|
||||
exceededPod := pods[1]
|
||||
failedPod := pods[2]
|
||||
|
||||
kl.HandlePodAdditions(pods)
|
||||
fittingPod := podWithUIDNameNsSpec("1", "fittingpod", "foo", fittingPodSpec)
|
||||
emptyPod := podWithUIDNameNsSpec("2", "emptypod", "foo", emptyPodSpec)
|
||||
missingPod := podWithUIDNameNsSpec("3", "missingpod", "foo", missingPodSpec)
|
||||
failedPod := podWithUIDNameNsSpec("4", "failedpod", "foo", failedPodSpec)
|
||||
|
||||
kl.HandlePodAdditions([]*v1.Pod{fittingPod, emptyPod, missingPod, failedPod})
|
||||
|
||||
// Check pod status stored in the status map.
|
||||
checkPodStatus(t, kl, fittingPod, v1.PodPending)
|
||||
checkPodStatus(t, kl, exceededPod, v1.PodFailed)
|
||||
checkPodStatus(t, kl, emptyPod, v1.PodFailed)
|
||||
checkPodStatus(t, kl, missingPod, v1.PodPending)
|
||||
checkPodStatus(t, kl, failedPod, v1.PodFailed)
|
||||
}
|
||||
|
||||
|
|
@ -733,7 +758,7 @@ func TestValidateContainerLogStatus(t *testing.T) {
|
|||
Running: &v1.ContainerStateRunning{},
|
||||
},
|
||||
LastTerminationState: v1.ContainerState{
|
||||
Terminated: &v1.ContainerStateTerminated{},
|
||||
Terminated: &v1.ContainerStateTerminated{ContainerID: "docker://fakeid"},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -761,9 +786,51 @@ func TestValidateContainerLogStatus(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
success: false,
|
||||
pSuccess: false,
|
||||
},
|
||||
{
|
||||
statuses: []v1.ContainerStatus{
|
||||
{
|
||||
Name: containerName,
|
||||
State: v1.ContainerState{
|
||||
Terminated: &v1.ContainerStateTerminated{ContainerID: "docker://fakeid"},
|
||||
},
|
||||
},
|
||||
},
|
||||
success: true,
|
||||
pSuccess: false,
|
||||
},
|
||||
{
|
||||
statuses: []v1.ContainerStatus{
|
||||
{
|
||||
Name: containerName,
|
||||
State: v1.ContainerState{
|
||||
Terminated: &v1.ContainerStateTerminated{},
|
||||
},
|
||||
LastTerminationState: v1.ContainerState{
|
||||
Terminated: &v1.ContainerStateTerminated{},
|
||||
},
|
||||
},
|
||||
},
|
||||
success: false,
|
||||
pSuccess: false,
|
||||
},
|
||||
{
|
||||
statuses: []v1.ContainerStatus{
|
||||
{
|
||||
Name: containerName,
|
||||
State: v1.ContainerState{
|
||||
Terminated: &v1.ContainerStateTerminated{},
|
||||
},
|
||||
LastTerminationState: v1.ContainerState{
|
||||
Terminated: &v1.ContainerStateTerminated{ContainerID: "docker://fakeid"},
|
||||
},
|
||||
},
|
||||
},
|
||||
success: true,
|
||||
pSuccess: true,
|
||||
},
|
||||
{
|
||||
statuses: []v1.ContainerStatus{
|
||||
{
|
||||
|
|
@ -2092,7 +2159,7 @@ func waitForVolumeUnmount(
|
|||
func() (bool, error) {
|
||||
// Verify volumes detached
|
||||
podVolumes = volumeManager.GetMountedVolumesForPod(
|
||||
volumehelper.GetUniquePodName(pod))
|
||||
util.GetUniquePodName(pod))
|
||||
|
||||
if len(podVolumes) != 0 {
|
||||
return false, nil
|
||||
|
|
|
|||
12
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_volumes.go
generated
vendored
12
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_volumes.go
generated
vendored
|
|
@ -57,6 +57,18 @@ func (kl *Kubelet) podVolumesExist(podUID types.UID) bool {
|
|||
volumetypes.UniquePodName(podUID)); len(mountedVolumes) > 0 {
|
||||
return true
|
||||
}
|
||||
// TODO: This checks pod volume paths and whether they are mounted. If checking returns error, podVolumesExist will return true
|
||||
// which means we consider volumes might exist and requires further checking.
|
||||
// There are some volume plugins such as flexvolume might not have mounts. See issue #61229
|
||||
volumePaths, err := kl.getMountedVolumePathListFromDisk(podUID)
|
||||
if err != nil {
|
||||
glog.Errorf("pod %q found, but error %v occurred during checking mounted volumes from disk", podUID, err)
|
||||
return true
|
||||
}
|
||||
if len(volumePaths) > 0 {
|
||||
glog.V(4).Infof("pod %q found, but volumes are still mounted on disk %v", podUID, volumePaths)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
16
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_volumes_test.go
generated
vendored
16
vendor/k8s.io/kubernetes/pkg/kubelet/kubelet_volumes_test.go
generated
vendored
|
|
@ -28,7 +28,7 @@ import (
|
|||
core "k8s.io/client-go/testing"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
|
||||
"k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
func TestListVolumesForPod(t *testing.T) {
|
||||
|
|
@ -64,7 +64,7 @@ func TestListVolumesForPod(t *testing.T) {
|
|||
err := kubelet.volumeManager.WaitForAttachAndMount(pod)
|
||||
assert.NoError(t, err)
|
||||
|
||||
podName := volumehelper.GetUniquePodName(pod)
|
||||
podName := util.GetUniquePodName(pod)
|
||||
|
||||
volumesToReturn, volumeExsit := kubelet.ListVolumesForPod(types.UID(podName))
|
||||
assert.True(t, volumeExsit, "expected to find volumes for pod %q", podName)
|
||||
|
|
@ -180,7 +180,7 @@ func TestVolumeAttachAndMountControllerDisabled(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
|
||||
podVolumes := kubelet.volumeManager.GetMountedVolumesForPod(
|
||||
volumehelper.GetUniquePodName(pod))
|
||||
util.GetUniquePodName(pod))
|
||||
|
||||
expectedPodVolumes := []string{"vol1"}
|
||||
assert.Len(t, podVolumes, len(expectedPodVolumes), "Volumes for pod %+v", pod)
|
||||
|
|
@ -227,7 +227,7 @@ func TestVolumeUnmountAndDetachControllerDisabled(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
|
||||
podVolumes := kubelet.volumeManager.GetMountedVolumesForPod(
|
||||
volumehelper.GetUniquePodName(pod))
|
||||
util.GetUniquePodName(pod))
|
||||
|
||||
expectedPodVolumes := []string{"vol1"}
|
||||
assert.Len(t, podVolumes, len(expectedPodVolumes), "Volumes for pod %+v", pod)
|
||||
|
|
@ -252,7 +252,7 @@ func TestVolumeUnmountAndDetachControllerDisabled(t *testing.T) {
|
|||
|
||||
// Verify volumes unmounted
|
||||
podVolumes = kubelet.volumeManager.GetMountedVolumesForPod(
|
||||
volumehelper.GetUniquePodName(pod))
|
||||
util.GetUniquePodName(pod))
|
||||
|
||||
assert.Len(t, podVolumes, 0,
|
||||
"Expected volumes to be unmounted and detached. But some volumes are still mounted: %#v", podVolumes)
|
||||
|
|
@ -317,7 +317,7 @@ func TestVolumeAttachAndMountControllerEnabled(t *testing.T) {
|
|||
assert.NoError(t, kubelet.volumeManager.WaitForAttachAndMount(pod))
|
||||
|
||||
podVolumes := kubelet.volumeManager.GetMountedVolumesForPod(
|
||||
volumehelper.GetUniquePodName(pod))
|
||||
util.GetUniquePodName(pod))
|
||||
|
||||
expectedPodVolumes := []string{"vol1"}
|
||||
assert.Len(t, podVolumes, len(expectedPodVolumes), "Volumes for pod %+v", pod)
|
||||
|
|
@ -386,7 +386,7 @@ func TestVolumeUnmountAndDetachControllerEnabled(t *testing.T) {
|
|||
assert.NoError(t, kubelet.volumeManager.WaitForAttachAndMount(pod))
|
||||
|
||||
podVolumes := kubelet.volumeManager.GetMountedVolumesForPod(
|
||||
volumehelper.GetUniquePodName(pod))
|
||||
util.GetUniquePodName(pod))
|
||||
|
||||
expectedPodVolumes := []string{"vol1"}
|
||||
assert.Len(t, podVolumes, len(expectedPodVolumes), "Volumes for pod %+v", pod)
|
||||
|
|
@ -410,7 +410,7 @@ func TestVolumeUnmountAndDetachControllerEnabled(t *testing.T) {
|
|||
|
||||
// Verify volumes unmounted
|
||||
podVolumes = kubelet.volumeManager.GetMountedVolumesForPod(
|
||||
volumehelper.GetUniquePodName(pod))
|
||||
util.GetUniquePodName(pod))
|
||||
|
||||
assert.Len(t, podVolumes, 0,
|
||||
"Expected volumes to be unmounted and detached. But some volumes are still mounted: %#v", podVolumes)
|
||||
|
|
|
|||
2
vendor/k8s.io/kubernetes/pkg/kubelet/pod_workers_test.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/kubelet/pod_workers_test.go
generated
vendored
|
|
@ -128,7 +128,6 @@ func drainWorkers(podWorkers *podWorkers, numPods int) {
|
|||
func TestUpdatePod(t *testing.T) {
|
||||
podWorkers, processed := createPodWorkers()
|
||||
|
||||
// Check whether all pod updates will be processed.
|
||||
numPods := 20
|
||||
for i := 0; i < numPods; i++ {
|
||||
for j := i; j < numPods; j++ {
|
||||
|
|
@ -151,6 +150,7 @@ func TestUpdatePod(t *testing.T) {
|
|||
continue
|
||||
}
|
||||
|
||||
// PodWorker guarantees the first and the last event will be processed
|
||||
first := 0
|
||||
last := len(processed[uid]) - 1
|
||||
if processed[uid][first].name != string(0) {
|
||||
|
|
|
|||
10
vendor/k8s.io/kubernetes/pkg/kubelet/runtime.go
generated
vendored
10
vendor/k8s.io/kubernetes/pkg/kubelet/runtime.go
generated
vendored
|
|
@ -29,7 +29,6 @@ type runtimeState struct {
|
|||
networkError error
|
||||
internalError error
|
||||
cidr string
|
||||
initError error
|
||||
healthChecks []*healthCheck
|
||||
}
|
||||
|
||||
|
|
@ -78,19 +77,10 @@ func (s *runtimeState) podCIDR() string {
|
|||
return s.cidr
|
||||
}
|
||||
|
||||
func (s *runtimeState) setInitError(err error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
s.initError = err
|
||||
}
|
||||
|
||||
func (s *runtimeState) runtimeErrors() []string {
|
||||
s.RLock()
|
||||
defer s.RUnlock()
|
||||
var ret []string
|
||||
if s.initError != nil {
|
||||
ret = append(ret, s.initError.Error())
|
||||
}
|
||||
if !s.lastBaseRuntimeSync.Add(s.baseRuntimeSyncThreshold).After(time.Now()) {
|
||||
ret = append(ret, "container runtime is down")
|
||||
}
|
||||
|
|
|
|||
2
vendor/k8s.io/kubernetes/pkg/kubelet/types/BUILD
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/kubelet/types/BUILD
generated
vendored
|
|
@ -18,6 +18,7 @@ go_library(
|
|||
importpath = "k8s.io/kubernetes/pkg/kubelet/types",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/scheduler/api:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
|
|
@ -32,7 +33,6 @@ go_test(
|
|||
"types_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/types",
|
||||
deps = [
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/require:go_default_library",
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/kubelet/types/constants.go
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/kubelet/types/constants.go
generated
vendored
|
|
@ -29,4 +29,5 @@ const (
|
|||
NodeAllocatableEnforcementKey = "pods"
|
||||
SystemReservedEnforcementKey = "system-reserved"
|
||||
KubeReservedEnforcementKey = "kube-reserved"
|
||||
NodeAllocatableNoneKey = "none"
|
||||
)
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/kubelet/types/labels.go
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/kubelet/types/labels.go
generated
vendored
|
|
@ -21,6 +21,7 @@ const (
|
|||
KubernetesPodNamespaceLabel = "io.kubernetes.pod.namespace"
|
||||
KubernetesPodUIDLabel = "io.kubernetes.pod.uid"
|
||||
KubernetesContainerNameLabel = "io.kubernetes.container.name"
|
||||
KubernetesContainerTypeLabel = "io.kubernetes.container.type"
|
||||
)
|
||||
|
||||
func GetContainerName(labels map[string]string) string {
|
||||
|
|
|
|||
22
vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go
generated
vendored
22
vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go
generated
vendored
|
|
@ -22,6 +22,7 @@ import (
|
|||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kubeapi "k8s.io/kubernetes/pkg/apis/core"
|
||||
schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -139,15 +140,16 @@ func (sp SyncPodType) String() string {
|
|||
}
|
||||
}
|
||||
|
||||
// IsCriticalPod returns true if the pod bears the critical pod annotation
|
||||
// key. Both the rescheduler and the kubelet use this key to make admission
|
||||
// and scheduling decisions.
|
||||
// IsCriticalPod returns true if the pod bears the critical pod annotation key or if pod's priority is greater than
|
||||
// or equal to SystemCriticalPriority. Both the rescheduler(deprecated in 1.10) and the kubelet use this function
|
||||
// to make admission and scheduling decisions.
|
||||
func IsCriticalPod(pod *v1.Pod) bool {
|
||||
return IsCritical(pod.Namespace, pod.Annotations)
|
||||
return IsCritical(pod.Namespace, pod.Annotations) || (pod.Spec.Priority != nil && IsCriticalPodBasedOnPriority(pod.Namespace, *pod.Spec.Priority))
|
||||
}
|
||||
|
||||
// IsCritical returns true if parameters bear the critical pod annotation
|
||||
// key. The DaemonSetController use this key directly to make scheduling decisions.
|
||||
// TODO: @ravig - Deprecated. Remove this when we move to resolving critical pods based on priorityClassName.
|
||||
func IsCritical(ns string, annotations map[string]string) bool {
|
||||
// Critical pods are restricted to "kube-system" namespace as of now.
|
||||
if ns != kubeapi.NamespaceSystem {
|
||||
|
|
@ -159,3 +161,15 @@ func IsCritical(ns string, annotations map[string]string) bool {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCriticalPodBasedOnPriority checks if the given pod is a critical pod based on priority resolved from pod Spec.
|
||||
func IsCriticalPodBasedOnPriority(ns string, priority int32) bool {
|
||||
// Critical pods are restricted to "kube-system" namespace as of now.
|
||||
if ns != kubeapi.NamespaceSystem {
|
||||
return false
|
||||
}
|
||||
if priority >= schedulerapi.SystemCriticalPriority {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
|||
2
vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update_test.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update_test.go
generated
vendored
|
|
@ -158,7 +158,7 @@ func TestIsCriticalPod(t *testing.T) {
|
|||
{
|
||||
pod: v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pod3",
|
||||
Name: "pod4",
|
||||
Namespace: "kube-system",
|
||||
Annotations: map[string]string{
|
||||
"scheduler.alpha.kubernetes.io/critical-pod": "",
|
||||
|
|
|
|||
9
vendor/k8s.io/kubernetes/pkg/kubelet/util/BUILD
generated
vendored
9
vendor/k8s.io/kubernetes/pkg/kubelet/util/BUILD
generated
vendored
|
|
@ -8,10 +8,13 @@ load(
|
|||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["util_test.go"],
|
||||
srcs = [
|
||||
"util_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/util",
|
||||
deps = ["//vendor/github.com/stretchr/testify/assert:go_default_library"],
|
||||
deps = [
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/kubelet/util/format/BUILD
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/kubelet/util/format/BUILD
generated
vendored
|
|
@ -23,7 +23,6 @@ go_test(
|
|||
name = "go_default_test",
|
||||
srcs = ["resources_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/util/format",
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
|
|
|
|||
2
vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go
generated
vendored
2
vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go
generated
vendored
|
|
@ -51,7 +51,7 @@ func PodWithDeletionTimestamp(pod *v1.Pod) string {
|
|||
return Pod(pod) + deletionTimestamp
|
||||
}
|
||||
|
||||
// Pods returns a string representating a list of pods in a human
|
||||
// Pods returns a string representation a list of pods in a human
|
||||
// readable format.
|
||||
func Pods(pods []*v1.Pod) string {
|
||||
return aggregatePods(pods, Pod)
|
||||
|
|
|
|||
1
vendor/k8s.io/kubernetes/pkg/kubelet/util/sliceutils/BUILD
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/kubelet/util/sliceutils/BUILD
generated
vendored
|
|
@ -33,7 +33,6 @@ go_test(
|
|||
name = "go_default_test",
|
||||
srcs = ["sliceutils_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/util/sliceutils",
|
||||
deps = [
|
||||
"//pkg/kubelet/container:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
|
|
|
|||
9
vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go
generated
vendored
9
vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go
generated
vendored
|
|
@ -31,3 +31,12 @@ func CreateListener(endpoint string) (net.Listener, error) {
|
|||
func GetAddressAndDialer(endpoint string) (string, func(addr string, timeout time.Duration) (net.Conn, error), error) {
|
||||
return "", nil, fmt.Errorf("GetAddressAndDialer is unsupported in this build")
|
||||
}
|
||||
|
||||
// LockAndCheckSubPath empty implementation
|
||||
func LockAndCheckSubPath(volumePath, subPath string) ([]uintptr, error) {
|
||||
return []uintptr{}, nil
|
||||
}
|
||||
|
||||
// UnlockPath empty implementation
|
||||
func UnlockPath(fileHandles []uintptr) {
|
||||
}
|
||||
|
|
|
|||
3
vendor/k8s.io/kubernetes/pkg/kubelet/volume_host.go
generated
vendored
3
vendor/k8s.io/kubernetes/pkg/kubelet/volume_host.go
generated
vendored
|
|
@ -36,6 +36,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/util/io"
|
||||
"k8s.io/kubernetes/pkg/util/mount"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
"k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
// NewInitializedVolumePluginMgr returns a new instance of
|
||||
|
|
@ -94,7 +95,7 @@ func (kvh *kubeletVolumeHost) GetVolumeDevicePluginDir(pluginName string) string
|
|||
func (kvh *kubeletVolumeHost) GetPodVolumeDir(podUID types.UID, pluginName string, volumeName string) string {
|
||||
dir := kvh.kubelet.getPodVolumeDir(podUID, pluginName, volumeName)
|
||||
if runtime.GOOS == "windows" {
|
||||
dir = volume.GetWindowsPath(dir)
|
||||
dir = util.GetWindowsPath(dir)
|
||||
}
|
||||
return dir
|
||||
}
|
||||
|
|
|
|||
11
vendor/k8s.io/kubernetes/pkg/master/BUILD
generated
vendored
11
vendor/k8s.io/kubernetes/pkg/master/BUILD
generated
vendored
|
|
@ -10,6 +10,7 @@ go_library(
|
|||
name = "go_default_library",
|
||||
srcs = [
|
||||
"client_ca_hook.go",
|
||||
"client_util.go",
|
||||
"controller.go",
|
||||
"doc.go",
|
||||
"import_known_versions.go",
|
||||
|
|
@ -67,6 +68,7 @@ go_library(
|
|||
"//pkg/registry/settings/rest:go_default_library",
|
||||
"//pkg/registry/storage/rest:go_default_library",
|
||||
"//pkg/routes:go_default_library",
|
||||
"//pkg/serviceaccount:go_default_library",
|
||||
"//pkg/util/async:go_default_library",
|
||||
"//pkg/util/node:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
|
|
@ -112,6 +114,8 @@ go_library(
|
|||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
size = "medium",
|
||||
timeout = "long",
|
||||
srcs = [
|
||||
"client_ca_hook_test.go",
|
||||
"controller_test.go",
|
||||
|
|
@ -120,7 +124,6 @@ go_test(
|
|||
"master_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/master",
|
||||
race = "off",
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
|
|
@ -132,6 +135,7 @@ go_test(
|
|||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/rbac:go_default_library",
|
||||
"//pkg/apis/storage:go_default_library",
|
||||
"//pkg/client/clientset_generated/internalclientset/fake:go_default_library",
|
||||
"//pkg/generated/openapi:go_default_library",
|
||||
"//pkg/kubelet/client:go_default_library",
|
||||
|
|
@ -145,13 +149,8 @@ go_test(
|
|||
"//vendor/github.com/go-openapi/strfmt:go_default_library",
|
||||
"//vendor/github.com/go-openapi/validate:go_default_library",
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/k8s.io/api/apps/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/batch/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/certificates/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
|
|
|
|||
4
vendor/k8s.io/kubernetes/pkg/master/client_ca_hook.go
generated
vendored
4
vendor/k8s.io/kubernetes/pkg/master/client_ca_hook.go
generated
vendored
|
|
@ -50,7 +50,7 @@ func (h ClientCARegistrationHook) PostStartHook(hookContext genericapiserver.Pos
|
|||
// We've seen lagging etcd before, so we want to retry this a few times before we decide to crashloop
|
||||
// the API server on it.
|
||||
err := wait.Poll(1*time.Second, 30*time.Second, func() (done bool, err error) {
|
||||
// retry building the config since sometimes the server can be in an inbetween state which caused
|
||||
// retry building the config since sometimes the server can be in an in-between state which caused
|
||||
// some kind of auto detection failure as I recall from other post start hooks.
|
||||
// TODO see if this is still true and fix the RBAC one too if it isn't.
|
||||
client, err := coreclient.NewForConfig(hookContext.LoopbackClientConfig)
|
||||
|
|
@ -74,7 +74,7 @@ func (h ClientCARegistrationHook) PostStartHook(hookContext genericapiserver.Pos
|
|||
// tryToWriteClientCAs is here for unit testing with a fake client. This is a wait.ConditionFunc so the bool
|
||||
// indicates if the condition was met. True when its finished, false when it should retry.
|
||||
func (h ClientCARegistrationHook) tryToWriteClientCAs(client coreclient.CoreInterface) (bool, error) {
|
||||
if _, err := client.Namespaces().Create(&api.Namespace{ObjectMeta: metav1.ObjectMeta{Name: metav1.NamespaceSystem}}); err != nil && !apierrors.IsAlreadyExists(err) {
|
||||
if err := createNamespaceIfNeeded(client, metav1.NamespaceSystem); err != nil {
|
||||
utilruntime.HandleError(err)
|
||||
return false, nil
|
||||
}
|
||||
|
|
|
|||
42
vendor/k8s.io/kubernetes/pkg/master/client_util.go
generated
vendored
Normal file
42
vendor/k8s.io/kubernetes/pkg/master/client_util.go
generated
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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 master
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||
)
|
||||
|
||||
func createNamespaceIfNeeded(c coreclient.NamespacesGetter, ns string) error {
|
||||
if _, err := c.Namespaces().Get(ns, metav1.GetOptions{}); err == nil {
|
||||
// the namespace already exists
|
||||
return nil
|
||||
}
|
||||
newNs := &api.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: ns,
|
||||
Namespace: "",
|
||||
},
|
||||
}
|
||||
_, err := c.Namespaces().Create(newNs)
|
||||
if err != nil && errors.IsAlreadyExists(err) {
|
||||
err = nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
23
vendor/k8s.io/kubernetes/pkg/master/controller.go
generated
vendored
23
vendor/k8s.io/kubernetes/pkg/master/controller.go
generated
vendored
|
|
@ -160,7 +160,7 @@ func (c *Controller) RunKubernetesNamespaces(ch chan struct{}) {
|
|||
wait.Until(func() {
|
||||
// Loop the system namespace list, and create them if they do not exist
|
||||
for _, ns := range c.SystemNamespaces {
|
||||
if err := c.CreateNamespaceIfNeeded(ns); err != nil {
|
||||
if err := createNamespaceIfNeeded(c.NamespaceClient, ns); err != nil {
|
||||
runtime.HandleError(fmt.Errorf("unable to create required kubernetes system namespace %s: %v", ns, err))
|
||||
}
|
||||
}
|
||||
|
|
@ -185,7 +185,7 @@ func (c *Controller) UpdateKubernetesService(reconcile bool) error {
|
|||
// TODO: when it becomes possible to change this stuff,
|
||||
// stop polling and start watching.
|
||||
// TODO: add endpoints of all replicas, not just the elected master.
|
||||
if err := c.CreateNamespaceIfNeeded(metav1.NamespaceDefault); err != nil {
|
||||
if err := createNamespaceIfNeeded(c.NamespaceClient, metav1.NamespaceDefault); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -200,25 +200,6 @@ func (c *Controller) UpdateKubernetesService(reconcile bool) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// CreateNamespaceIfNeeded will create a namespace if it doesn't already exist
|
||||
func (c *Controller) CreateNamespaceIfNeeded(ns string) error {
|
||||
if _, err := c.NamespaceClient.Namespaces().Get(ns, metav1.GetOptions{}); err == nil {
|
||||
// the namespace already exists
|
||||
return nil
|
||||
}
|
||||
newNs := &api.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: ns,
|
||||
Namespace: "",
|
||||
},
|
||||
}
|
||||
_, err := c.NamespaceClient.Namespaces().Create(newNs)
|
||||
if err != nil && errors.IsAlreadyExists(err) {
|
||||
err = nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// createPortAndServiceSpec creates an array of service ports.
|
||||
// If the NodePort value is 0, just the servicePort is used, otherwise, a node port is exposed.
|
||||
func createPortAndServiceSpec(servicePort int, targetServicePort int, nodePort int, servicePortName string, extraServicePorts []api.ServicePort) ([]api.ServicePort, api.ServiceType) {
|
||||
|
|
|
|||
47
vendor/k8s.io/kubernetes/pkg/master/master.go
generated
vendored
47
vendor/k8s.io/kubernetes/pkg/master/master.go
generated
vendored
|
|
@ -65,6 +65,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/registry/core/endpoint"
|
||||
endpointsstorage "k8s.io/kubernetes/pkg/registry/core/endpoint/storage"
|
||||
"k8s.io/kubernetes/pkg/routes"
|
||||
"k8s.io/kubernetes/pkg/serviceaccount"
|
||||
nodeutil "k8s.io/kubernetes/pkg/util/node"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
|
@ -109,7 +110,6 @@ type ExtraConfig struct {
|
|||
|
||||
// Used to start and monitor tunneling
|
||||
Tunneler tunneler.Tunneler
|
||||
EnableUISupport bool
|
||||
EnableLogsSupport bool
|
||||
ProxyTransport http.RoundTripper
|
||||
|
||||
|
|
@ -156,6 +156,9 @@ type ExtraConfig struct {
|
|||
|
||||
// Selects which reconciler to use
|
||||
EndpointReconcilerType reconcilers.Type
|
||||
|
||||
ServiceAccountIssuer serviceaccount.TokenGenerator
|
||||
ServiceAccountAPIAudiences []string
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
|
|
@ -269,9 +272,6 @@ func (cfg *Config) Complete(informers informers.SharedInformerFactory) Completed
|
|||
glog.Infof("Node port range unspecified. Defaulting to %v.", c.ExtraConfig.ServiceNodePortRange)
|
||||
}
|
||||
|
||||
// enable swagger UI only if general UI support is on
|
||||
c.GenericConfig.EnableSwaggerUI = c.GenericConfig.EnableSwaggerUI && c.ExtraConfig.EnableUISupport
|
||||
|
||||
if c.ExtraConfig.EndpointReconcilerConfig.Interval == 0 {
|
||||
c.ExtraConfig.EndpointReconcilerConfig.Interval = DefaultEndpointReconcilerInterval
|
||||
}
|
||||
|
|
@ -304,9 +304,6 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if c.ExtraConfig.EnableUISupport {
|
||||
routes.UIRedirect{}.Install(s.Handler.NonGoRestfulMux)
|
||||
}
|
||||
if c.ExtraConfig.EnableLogsSupport {
|
||||
routes.Logs{}.Install(s.Handler.GoRestfulContainer)
|
||||
}
|
||||
|
|
@ -316,15 +313,17 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
|
|||
}
|
||||
|
||||
// install legacy rest storage
|
||||
if c.ExtraConfig.APIResourceConfigSource.AnyResourcesForVersionEnabled(apiv1.SchemeGroupVersion) {
|
||||
if c.ExtraConfig.APIResourceConfigSource.VersionEnabled(apiv1.SchemeGroupVersion) {
|
||||
legacyRESTStorageProvider := corerest.LegacyRESTStorageProvider{
|
||||
StorageFactory: c.ExtraConfig.StorageFactory,
|
||||
ProxyTransport: c.ExtraConfig.ProxyTransport,
|
||||
KubeletClientConfig: c.ExtraConfig.KubeletClientConfig,
|
||||
EventTTL: c.ExtraConfig.EventTTL,
|
||||
ServiceIPRange: c.ExtraConfig.ServiceIPRange,
|
||||
ServiceNodePortRange: c.ExtraConfig.ServiceNodePortRange,
|
||||
LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig,
|
||||
StorageFactory: c.ExtraConfig.StorageFactory,
|
||||
ProxyTransport: c.ExtraConfig.ProxyTransport,
|
||||
KubeletClientConfig: c.ExtraConfig.KubeletClientConfig,
|
||||
EventTTL: c.ExtraConfig.EventTTL,
|
||||
ServiceIPRange: c.ExtraConfig.ServiceIPRange,
|
||||
ServiceNodePortRange: c.ExtraConfig.ServiceNodePortRange,
|
||||
LoopbackClientConfig: c.GenericConfig.LoopbackClientConfig,
|
||||
ServiceAccountIssuer: c.ExtraConfig.ServiceAccountIssuer,
|
||||
ServiceAccountAPIAudiences: c.ExtraConfig.ServiceAccountAPIAudiences,
|
||||
}
|
||||
m.InstallLegacyAPI(&c, c.GenericConfig.RESTOptionsGetter, legacyRESTStorageProvider)
|
||||
}
|
||||
|
|
@ -337,15 +336,15 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
|
|||
// TODO: describe the priority all the way down in the RESTStorageProviders and plumb it back through the various discovery
|
||||
// handlers that we have.
|
||||
restStorageProviders := []RESTStorageProvider{
|
||||
authenticationrest.RESTStorageProvider{Authenticator: c.GenericConfig.Authenticator},
|
||||
authorizationrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorizer, RuleResolver: c.GenericConfig.RuleResolver},
|
||||
authenticationrest.RESTStorageProvider{Authenticator: c.GenericConfig.Authentication.Authenticator},
|
||||
authorizationrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer, RuleResolver: c.GenericConfig.RuleResolver},
|
||||
autoscalingrest.RESTStorageProvider{},
|
||||
batchrest.RESTStorageProvider{},
|
||||
certificatesrest.RESTStorageProvider{},
|
||||
extensionsrest.RESTStorageProvider{},
|
||||
networkingrest.RESTStorageProvider{},
|
||||
policyrest.RESTStorageProvider{},
|
||||
rbacrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorizer},
|
||||
rbacrest.RESTStorageProvider{Authorizer: c.GenericConfig.Authorization.Authorizer},
|
||||
schedulingrest.RESTStorageProvider{},
|
||||
settingsrest.RESTStorageProvider{},
|
||||
storagerest.RESTStorageProvider{},
|
||||
|
|
@ -406,7 +405,7 @@ func (m *Master) InstallAPIs(apiResourceConfigSource serverstorage.APIResourceCo
|
|||
|
||||
for _, restStorageBuilder := range restStorageProviders {
|
||||
groupName := restStorageBuilder.GroupName()
|
||||
if !apiResourceConfigSource.AnyResourcesForGroupEnabled(groupName) {
|
||||
if !apiResourceConfigSource.AnyVersionForGroupEnabled(groupName) {
|
||||
glog.V(1).Infof("Skipping disabled API group %q.", groupName)
|
||||
continue
|
||||
}
|
||||
|
|
@ -487,15 +486,5 @@ func DefaultAPIResourceConfigSource() *serverstorage.ResourceConfig {
|
|||
admissionregistrationv1beta1.SchemeGroupVersion,
|
||||
)
|
||||
|
||||
// all extensions resources except these are disabled by default
|
||||
ret.EnableResources(
|
||||
extensionsapiv1beta1.SchemeGroupVersion.WithResource("daemonsets"),
|
||||
extensionsapiv1beta1.SchemeGroupVersion.WithResource("deployments"),
|
||||
extensionsapiv1beta1.SchemeGroupVersion.WithResource("ingresses"),
|
||||
extensionsapiv1beta1.SchemeGroupVersion.WithResource("networkpolicies"),
|
||||
extensionsapiv1beta1.SchemeGroupVersion.WithResource("replicasets"),
|
||||
extensionsapiv1beta1.SchemeGroupVersion.WithResource("podsecuritypolicies"),
|
||||
)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
|
|
|||
43
vendor/k8s.io/kubernetes/pkg/master/master_test.go
generated
vendored
43
vendor/k8s.io/kubernetes/pkg/master/master_test.go
generated
vendored
|
|
@ -27,13 +27,8 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
appsapiv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
autoscalingapiv1 "k8s.io/api/autoscaling/v1"
|
||||
batchapiv1 "k8s.io/api/batch/v1"
|
||||
batchapiv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
certificatesapiv1beta1 "k8s.io/api/certificates/v1beta1"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
extensionsapiv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
|
@ -58,6 +53,7 @@ import (
|
|||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/rbac"
|
||||
"k8s.io/kubernetes/pkg/apis/storage"
|
||||
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
||||
"k8s.io/kubernetes/pkg/master/reconcilers"
|
||||
certificatesrest "k8s.io/kubernetes/pkg/registry/certificates/rest"
|
||||
|
|
@ -88,13 +84,18 @@ func setUp(t *testing.T) (*etcdtesting.EtcdTestServer, Config, informers.SharedI
|
|||
resourceEncoding.SetVersionEncoding(batch.GroupName, *testapi.Batch.GroupVersion(), schema.GroupVersion{Group: batch.GroupName, Version: runtime.APIVersionInternal})
|
||||
// FIXME (soltysh): this GroupVersionResource override should be configurable
|
||||
resourceEncoding.SetResourceEncoding(schema.GroupResource{Group: "batch", Resource: "cronjobs"}, schema.GroupVersion{Group: batch.GroupName, Version: "v1beta1"}, schema.GroupVersion{Group: batch.GroupName, Version: runtime.APIVersionInternal})
|
||||
resourceEncoding.SetResourceEncoding(schema.GroupResource{Group: "storage.k8s.io", Resource: "volumeattachments"}, schema.GroupVersion{Group: storage.GroupName, Version: "v1beta1"}, schema.GroupVersion{Group: storage.GroupName, Version: runtime.APIVersionInternal})
|
||||
|
||||
resourceEncoding.SetVersionEncoding(apps.GroupName, *testapi.Apps.GroupVersion(), schema.GroupVersion{Group: apps.GroupName, Version: runtime.APIVersionInternal})
|
||||
resourceEncoding.SetVersionEncoding(extensions.GroupName, *testapi.Extensions.GroupVersion(), schema.GroupVersion{Group: extensions.GroupName, Version: runtime.APIVersionInternal})
|
||||
resourceEncoding.SetVersionEncoding(rbac.GroupName, *testapi.Rbac.GroupVersion(), schema.GroupVersion{Group: rbac.GroupName, Version: runtime.APIVersionInternal})
|
||||
resourceEncoding.SetVersionEncoding(certificates.GroupName, *testapi.Certificates.GroupVersion(), schema.GroupVersion{Group: certificates.GroupName, Version: runtime.APIVersionInternal})
|
||||
storageFactory := serverstorage.NewDefaultStorageFactory(*storageConfig, testapi.StorageMediaType(), legacyscheme.Codecs, resourceEncoding, DefaultAPIResourceConfigSource(), nil)
|
||||
|
||||
err := options.NewEtcdOptions(storageConfig).ApplyWithStorageFactoryTo(storageFactory, config.GenericConfig)
|
||||
etcdOptions := options.NewEtcdOptions(storageConfig)
|
||||
// unit tests don't need watch cache and it leaks lots of goroutines with etcd testing functions during unit tests
|
||||
etcdOptions.EnableWatchCache = false
|
||||
err := etcdOptions.ApplyWithStorageFactoryTo(storageFactory, config.GenericConfig)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -194,32 +195,6 @@ func newMaster(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *ass
|
|||
return master, etcdserver, config, assert
|
||||
}
|
||||
|
||||
// limitedAPIResourceConfigSource only enables the core group, the extensions group, the batch group, and the autoscaling group.
|
||||
func limitedAPIResourceConfigSource() *serverstorage.ResourceConfig {
|
||||
ret := serverstorage.NewResourceConfig()
|
||||
ret.EnableVersions(
|
||||
apiv1.SchemeGroupVersion,
|
||||
extensionsapiv1beta1.SchemeGroupVersion,
|
||||
batchapiv1.SchemeGroupVersion,
|
||||
batchapiv1beta1.SchemeGroupVersion,
|
||||
appsapiv1beta1.SchemeGroupVersion,
|
||||
autoscalingapiv1.SchemeGroupVersion,
|
||||
)
|
||||
return ret
|
||||
}
|
||||
|
||||
// newLimitedMaster only enables the core group, the extensions group, the batch group, and the autoscaling group.
|
||||
func newLimitedMaster(t *testing.T) (*Master, *etcdtesting.EtcdTestServer, Config, *assert.Assertions) {
|
||||
etcdserver, config, sharedInformers, assert := setUp(t)
|
||||
config.ExtraConfig.APIResourceConfigSource = limitedAPIResourceConfigSource()
|
||||
master, err := config.Complete(sharedInformers).New(genericapiserver.EmptyDelegate)
|
||||
if err != nil {
|
||||
t.Fatalf("Error in bringing up the master: %v", err)
|
||||
}
|
||||
|
||||
return master, etcdserver, config, assert
|
||||
}
|
||||
|
||||
// TestVersion tests /version
|
||||
func TestVersion(t *testing.T) {
|
||||
s, etcdserver, _, _ := newMaster(t)
|
||||
|
|
@ -377,8 +352,8 @@ func TestAPIVersionOfDiscoveryEndpoints(t *testing.T) {
|
|||
|
||||
func TestNoAlphaVersionsEnabledByDefault(t *testing.T) {
|
||||
config := DefaultAPIResourceConfigSource()
|
||||
for gv, gvConfig := range config.GroupVersionResourceConfigs {
|
||||
if gvConfig.Enable && strings.Contains(gv.Version, "alpha") {
|
||||
for gv, enable := range config.GroupVersionConfigs {
|
||||
if enable && strings.Contains(gv.Version, "alpha") {
|
||||
t.Errorf("Alpha API version %s enabled by default", gv.String())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
vendor/k8s.io/kubernetes/pkg/master/ports/ports.go
generated
vendored
10
vendor/k8s.io/kubernetes/pkg/master/ports/ports.go
generated
vendored
|
|
@ -26,12 +26,12 @@ const (
|
|||
// SchedulerPort is the default port for the scheduler status server.
|
||||
// May be overridden by a flag at startup.
|
||||
SchedulerPort = 10251
|
||||
// ControllerManagerPort is the default port for the controller manager status server.
|
||||
// InsecureKubeControllerManagerPort is the default port for the controller manager status server.
|
||||
// May be overridden by a flag at startup.
|
||||
ControllerManagerPort = 10252
|
||||
// CloudControllerManagerPort is the default port for the cloud controller manager server.
|
||||
// This value may be overriden by a flag at startup.
|
||||
CloudControllerManagerPort = 10253
|
||||
InsecureKubeControllerManagerPort = 10252
|
||||
// InsecureCloudControllerManagerPort is the default port for the cloud controller manager server.
|
||||
// This value may be overridden by a flag at startup.
|
||||
InsecureCloudControllerManagerPort = 10253
|
||||
// KubeletReadOnlyPort exposes basic read-only services from the kubelet.
|
||||
// May be overridden by a flag at startup.
|
||||
// This is necessary for heapster to collect monitoring stats from the kubelet
|
||||
|
|
|
|||
12
vendor/k8s.io/kubernetes/pkg/master/services.go
generated
vendored
12
vendor/k8s.io/kubernetes/pkg/master/services.go
generated
vendored
|
|
@ -21,23 +21,17 @@ import (
|
|||
"net"
|
||||
|
||||
"github.com/golang/glog"
|
||||
|
||||
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
|
||||
"k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
||||
)
|
||||
|
||||
// DefaultServiceIPRange takes a the serviceIPRange flag and returns the defaulted service ip range (if needed),
|
||||
// api server service IP, and an error
|
||||
// TODO move this out of the genericapiserver package
|
||||
func DefaultServiceIPRange(passedServiceClusterIPRange net.IPNet) (net.IPNet, net.IP, error) {
|
||||
serviceClusterIPRange := passedServiceClusterIPRange
|
||||
if passedServiceClusterIPRange.IP == nil {
|
||||
defaultNet := "10.0.0.0/24"
|
||||
glog.Infof("Network range for service cluster IPs is unspecified. Defaulting to %v.", defaultNet)
|
||||
_, defaultServiceClusterIPRange, err := net.ParseCIDR(defaultNet)
|
||||
if err != nil {
|
||||
return net.IPNet{}, net.IP{}, err
|
||||
}
|
||||
serviceClusterIPRange = *defaultServiceClusterIPRange
|
||||
glog.Infof("Network range for service cluster IPs is unspecified. Defaulting to %v.", kubeoptions.DefaultServiceIPCIDR)
|
||||
serviceClusterIPRange = kubeoptions.DefaultServiceIPCIDR
|
||||
}
|
||||
if size := ipallocator.RangeSize(&serviceClusterIPRange); size < 8 {
|
||||
return net.IPNet{}, net.IP{}, fmt.Errorf("The service cluster IP range must be at least %d IP addresses", 8)
|
||||
|
|
|
|||
88
vendor/k8s.io/kubernetes/pkg/scheduler/BUILD
generated
vendored
Normal file
88
vendor/k8s.io/kubernetes/pkg/scheduler/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
"go_test",
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["scheduler_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/controller/volume/persistentvolume:go_default_library",
|
||||
"//pkg/scheduler/algorithm:go_default_library",
|
||||
"//pkg/scheduler/algorithm/predicates:go_default_library",
|
||||
"//pkg/scheduler/core:go_default_library",
|
||||
"//pkg/scheduler/schedulercache:go_default_library",
|
||||
"//pkg/scheduler/testing:go_default_library",
|
||||
"//pkg/scheduler/util:go_default_library",
|
||||
"//pkg/scheduler/volumebinder:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"scheduler.go",
|
||||
"testutil.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/scheduler",
|
||||
deps = [
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/scheduler/algorithm:go_default_library",
|
||||
"//pkg/scheduler/algorithm/predicates:go_default_library",
|
||||
"//pkg/scheduler/api:go_default_library",
|
||||
"//pkg/scheduler/core:go_default_library",
|
||||
"//pkg/scheduler/metrics:go_default_library",
|
||||
"//pkg/scheduler/schedulercache:go_default_library",
|
||||
"//pkg/scheduler/util:go_default_library",
|
||||
"//pkg/scheduler/volumebinder:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//vendor/k8s.io/client-go/listers/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/scheduler/algorithm:all-srcs",
|
||||
"//pkg/scheduler/algorithmprovider:all-srcs",
|
||||
"//pkg/scheduler/api:all-srcs",
|
||||
"//pkg/scheduler/core:all-srcs",
|
||||
"//pkg/scheduler/factory:all-srcs",
|
||||
"//pkg/scheduler/metrics:all-srcs",
|
||||
"//pkg/scheduler/schedulercache:all-srcs",
|
||||
"//pkg/scheduler/testing:all-srcs",
|
||||
"//pkg/scheduler/util:all-srcs",
|
||||
"//pkg/scheduler/volumebinder:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
4
vendor/k8s.io/kubernetes/pkg/scheduler/OWNERS
generated
vendored
Normal file
4
vendor/k8s.io/kubernetes/pkg/scheduler/OWNERS
generated
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
approvers:
|
||||
- sig-scheduling-maintainers
|
||||
reviewers:
|
||||
- sig-scheduling
|
||||
43
vendor/k8s.io/kubernetes/pkg/scheduler/api/BUILD
generated
vendored
Normal file
43
vendor/k8s.io/kubernetes/pkg/scheduler/api/BUILD
generated
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"doc.go",
|
||||
"register.go",
|
||||
"types.go",
|
||||
"zz_generated.deepcopy.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/scheduler/api",
|
||||
deps = [
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
"//vendor/k8s.io/client-go/rest:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [
|
||||
":package-srcs",
|
||||
"//pkg/scheduler/api/latest:all-srcs",
|
||||
"//pkg/scheduler/api/v1:all-srcs",
|
||||
"//pkg/scheduler/api/validation:all-srcs",
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
20
vendor/k8s.io/kubernetes/pkg/scheduler/api/doc.go
generated
vendored
Normal file
20
vendor/k8s.io/kubernetes/pkg/scheduler/api/doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// Package api contains scheduler API objects.
|
||||
package api // import "k8s.io/kubernetes/pkg/scheduler/api"
|
||||
55
vendor/k8s.io/kubernetes/pkg/scheduler/api/register.go
generated
vendored
Normal file
55
vendor/k8s.io/kubernetes/pkg/scheduler/api/register.go
generated
vendored
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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 api
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// Scheme is the default instance of runtime.Scheme to which types in the Kubernetes API are already registered.
|
||||
// TODO: remove this, scheduler should not have its own scheme.
|
||||
var Scheme = runtime.NewScheme()
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
// TODO this should be in the "scheduler" group
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: "", Version: runtime.APIVersionInternal}
|
||||
|
||||
var (
|
||||
// SchemeBuilder defines a SchemeBuilder object.
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
// AddToScheme is used to add stored functions to scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
func init() {
|
||||
if err := addKnownTypes(Scheme); err != nil {
|
||||
// Programmer error.
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
if err := scheme.AddIgnoredConversionType(&metav1.TypeMeta{}, &metav1.TypeMeta{}); err != nil {
|
||||
return err
|
||||
}
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&Policy{},
|
||||
)
|
||||
return nil
|
||||
}
|
||||
281
vendor/k8s.io/kubernetes/pkg/scheduler/api/types.go
generated
vendored
Normal file
281
vendor/k8s.io/kubernetes/pkg/scheduler/api/types.go
generated
vendored
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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 api
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
const (
|
||||
// MaxUint defines the max unsigned int value.
|
||||
MaxUint = ^uint(0)
|
||||
// MaxInt defines the max signed int value.
|
||||
MaxInt = int(MaxUint >> 1)
|
||||
// MaxTotalPriority defines the max total priority value.
|
||||
MaxTotalPriority = MaxInt
|
||||
// MaxPriority defines the max priority value.
|
||||
MaxPriority = 10
|
||||
// MaxWeight defines the max weight value.
|
||||
MaxWeight = MaxInt / MaxPriority
|
||||
// HighestUserDefinablePriority is the highest priority for user defined priority classes. Priority values larger than 1 billion are reserved for Kubernetes system use.
|
||||
HighestUserDefinablePriority = int32(1000000000)
|
||||
// SystemCriticalPriority is the beginning of the range of priority values for critical system components.
|
||||
SystemCriticalPriority = 2 * HighestUserDefinablePriority
|
||||
// NOTE: In order to avoid conflict of names with user-defined priority classes, all the names must
|
||||
// start with scheduling.SystemPriorityClassPrefix which is by default "system-".
|
||||
SystemClusterCritical = "system-cluster-critical"
|
||||
SystemNodeCritical = "system-node-critical"
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// Policy describes a struct of a policy resource in api.
|
||||
type Policy struct {
|
||||
metav1.TypeMeta
|
||||
// Holds the information to configure the fit predicate functions.
|
||||
// If unspecified, the default predicate functions will be applied.
|
||||
// If empty list, all predicates (except the mandatory ones) will be
|
||||
// bypassed.
|
||||
Predicates []PredicatePolicy
|
||||
// Holds the information to configure the priority functions.
|
||||
// If unspecified, the default priority functions will be applied.
|
||||
// If empty list, all priority functions will be bypassed.
|
||||
Priorities []PriorityPolicy
|
||||
// Holds the information to communicate with the extender(s)
|
||||
ExtenderConfigs []ExtenderConfig
|
||||
// RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule
|
||||
// corresponding to every RequiredDuringScheduling affinity rule.
|
||||
// HardPodAffinitySymmetricWeight represents the weight of implicit PreferredDuringScheduling affinity rule, in the range 1-100.
|
||||
HardPodAffinitySymmetricWeight int32
|
||||
|
||||
// When AlwaysCheckAllPredicates is set to true, scheduler checks all
|
||||
// the configured predicates even after one or more of them fails.
|
||||
// When the flag is set to false, scheduler skips checking the rest
|
||||
// of the predicates after it finds one predicate that failed.
|
||||
AlwaysCheckAllPredicates bool
|
||||
}
|
||||
|
||||
// PredicatePolicy describes a struct of a predicate policy.
|
||||
type PredicatePolicy struct {
|
||||
// Identifier of the predicate policy
|
||||
// For a custom predicate, the name can be user-defined
|
||||
// For the Kubernetes provided predicates, the name is the identifier of the pre-defined predicate
|
||||
Name string
|
||||
// Holds the parameters to configure the given predicate
|
||||
Argument *PredicateArgument
|
||||
}
|
||||
|
||||
// PriorityPolicy describes a struct of a priority policy.
|
||||
type PriorityPolicy struct {
|
||||
// Identifier of the priority policy
|
||||
// For a custom priority, the name can be user-defined
|
||||
// For the Kubernetes provided priority functions, the name is the identifier of the pre-defined priority function
|
||||
Name string
|
||||
// The numeric multiplier for the node scores that the priority function generates
|
||||
// The weight should be a positive integer
|
||||
Weight int
|
||||
// Holds the parameters to configure the given priority function
|
||||
Argument *PriorityArgument
|
||||
}
|
||||
|
||||
// PredicateArgument represents the arguments to configure predicate functions in scheduler policy configuration.
|
||||
// Only one of its members may be specified
|
||||
type PredicateArgument struct {
|
||||
// The predicate that provides affinity for pods belonging to a service
|
||||
// It uses a label to identify nodes that belong to the same "group"
|
||||
ServiceAffinity *ServiceAffinity
|
||||
// The predicate that checks whether a particular node has a certain label
|
||||
// defined or not, regardless of value
|
||||
LabelsPresence *LabelsPresence
|
||||
}
|
||||
|
||||
// PriorityArgument represents the arguments to configure priority functions in scheduler policy configuration.
|
||||
// Only one of its members may be specified
|
||||
type PriorityArgument struct {
|
||||
// The priority function that ensures a good spread (anti-affinity) for pods belonging to a service
|
||||
// It uses a label to identify nodes that belong to the same "group"
|
||||
ServiceAntiAffinity *ServiceAntiAffinity
|
||||
// The priority function that checks whether a particular node has a certain label
|
||||
// defined or not, regardless of value
|
||||
LabelPreference *LabelPreference
|
||||
}
|
||||
|
||||
// ServiceAffinity holds the parameters that are used to configure the corresponding predicate in scheduler policy configuration.
|
||||
type ServiceAffinity struct {
|
||||
// The list of labels that identify node "groups"
|
||||
// All of the labels should match for the node to be considered a fit for hosting the pod
|
||||
Labels []string
|
||||
}
|
||||
|
||||
// LabelsPresence holds the parameters that are used to configure the corresponding predicate in scheduler policy configuration.
|
||||
type LabelsPresence struct {
|
||||
// The list of labels that identify node "groups"
|
||||
// All of the labels should be either present (or absent) for the node to be considered a fit for hosting the pod
|
||||
Labels []string
|
||||
// The boolean flag that indicates whether the labels should be present or absent from the node
|
||||
Presence bool
|
||||
}
|
||||
|
||||
// ServiceAntiAffinity holds the parameters that are used to configure the corresponding priority function
|
||||
type ServiceAntiAffinity struct {
|
||||
// Used to identify node "groups"
|
||||
Label string
|
||||
}
|
||||
|
||||
// LabelPreference holds the parameters that are used to configure the corresponding priority function
|
||||
type LabelPreference struct {
|
||||
// Used to identify node "groups"
|
||||
Label string
|
||||
// This is a boolean flag
|
||||
// If true, higher priority is given to nodes that have the label
|
||||
// If false, higher priority is given to nodes that do not have the label
|
||||
Presence bool
|
||||
}
|
||||
|
||||
// ExtenderManagedResource describes the arguments of extended resources
|
||||
// managed by an extender.
|
||||
type ExtenderManagedResource struct {
|
||||
// Name is the extended resource name.
|
||||
Name v1.ResourceName
|
||||
// IgnoredByScheduler indicates whether kube-scheduler should ignore this
|
||||
// resource when applying predicates.
|
||||
IgnoredByScheduler bool
|
||||
}
|
||||
|
||||
// ExtenderConfig holds the parameters used to communicate with the extender. If a verb is unspecified/empty,
|
||||
// it is assumed that the extender chose not to provide that extension.
|
||||
type ExtenderConfig struct {
|
||||
// URLPrefix at which the extender is available
|
||||
URLPrefix string
|
||||
// Verb for the filter call, empty if not supported. This verb is appended to the URLPrefix when issuing the filter call to extender.
|
||||
FilterVerb string
|
||||
// Verb for the prioritize call, empty if not supported. This verb is appended to the URLPrefix when issuing the prioritize call to extender.
|
||||
PrioritizeVerb string
|
||||
// The numeric multiplier for the node scores that the prioritize call generates.
|
||||
// The weight should be a positive integer
|
||||
Weight int
|
||||
// Verb for the bind call, empty if not supported. This verb is appended to the URLPrefix when issuing the bind call to extender.
|
||||
// If this method is implemented by the extender, it is the extender's responsibility to bind the pod to apiserver. Only one extender
|
||||
// can implement this function.
|
||||
BindVerb string
|
||||
// EnableHTTPS specifies whether https should be used to communicate with the extender
|
||||
EnableHTTPS bool
|
||||
// TLSConfig specifies the transport layer security config
|
||||
TLSConfig *restclient.TLSClientConfig
|
||||
// HTTPTimeout specifies the timeout duration for a call to the extender. Filter timeout fails the scheduling of the pod. Prioritize
|
||||
// timeout is ignored, k8s/other extenders priorities are used to select the node.
|
||||
HTTPTimeout time.Duration
|
||||
// NodeCacheCapable specifies that the extender is capable of caching node information,
|
||||
// so the scheduler should only send minimal information about the eligible nodes
|
||||
// assuming that the extender already cached full details of all nodes in the cluster
|
||||
NodeCacheCapable bool
|
||||
// ManagedResources is a list of extended resources that are managed by
|
||||
// this extender.
|
||||
// - A pod will be sent to the extender on the Filter, Prioritize and Bind
|
||||
// (if the extender is the binder) phases iff the pod requests at least
|
||||
// one of the extended resources in this list. If empty or unspecified,
|
||||
// all pods will be sent to this extender.
|
||||
// - If IgnoredByScheduler is set to true for a resource, kube-scheduler
|
||||
// will skip checking the resource in predicates.
|
||||
// +optional
|
||||
ManagedResources []ExtenderManagedResource
|
||||
}
|
||||
|
||||
// ExtenderArgs represents the arguments needed by the extender to filter/prioritize
|
||||
// nodes for a pod.
|
||||
type ExtenderArgs struct {
|
||||
// Pod being scheduled
|
||||
Pod v1.Pod
|
||||
// List of candidate nodes where the pod can be scheduled; to be populated
|
||||
// only if ExtenderConfig.NodeCacheCapable == false
|
||||
Nodes *v1.NodeList
|
||||
// List of candidate node names where the pod can be scheduled; to be
|
||||
// populated only if ExtenderConfig.NodeCacheCapable == true
|
||||
NodeNames *[]string
|
||||
}
|
||||
|
||||
// FailedNodesMap represents the filtered out nodes, with node names and failure messages
|
||||
type FailedNodesMap map[string]string
|
||||
|
||||
// ExtenderFilterResult represents the results of a filter call to an extender
|
||||
type ExtenderFilterResult struct {
|
||||
// Filtered set of nodes where the pod can be scheduled; to be populated
|
||||
// only if ExtenderConfig.NodeCacheCapable == false
|
||||
Nodes *v1.NodeList
|
||||
// Filtered set of nodes where the pod can be scheduled; to be populated
|
||||
// only if ExtenderConfig.NodeCacheCapable == true
|
||||
NodeNames *[]string
|
||||
// Filtered out nodes where the pod can't be scheduled and the failure messages
|
||||
FailedNodes FailedNodesMap
|
||||
// Error message indicating failure
|
||||
Error string
|
||||
}
|
||||
|
||||
// ExtenderBindingArgs represents the arguments to an extender for binding a pod to a node.
|
||||
type ExtenderBindingArgs struct {
|
||||
// PodName is the name of the pod being bound
|
||||
PodName string
|
||||
// PodNamespace is the namespace of the pod being bound
|
||||
PodNamespace string
|
||||
// PodUID is the UID of the pod being bound
|
||||
PodUID types.UID
|
||||
// Node selected by the scheduler
|
||||
Node string
|
||||
}
|
||||
|
||||
// ExtenderBindingResult represents the result of binding of a pod to a node from an extender.
|
||||
type ExtenderBindingResult struct {
|
||||
// Error message indicating failure
|
||||
Error string
|
||||
}
|
||||
|
||||
// HostPriority represents the priority of scheduling to a particular host, higher priority is better.
|
||||
type HostPriority struct {
|
||||
// Name of the host
|
||||
Host string
|
||||
// Score associated with the host
|
||||
Score int
|
||||
}
|
||||
|
||||
// HostPriorityList declares a []HostPriority type.
|
||||
type HostPriorityList []HostPriority
|
||||
|
||||
// SystemPriorityClasses defines special priority classes which are used by system critical pods that should not be preempted by workload pods.
|
||||
var SystemPriorityClasses = map[string]int32{
|
||||
SystemClusterCritical: SystemCriticalPriority,
|
||||
SystemNodeCritical: SystemCriticalPriority + 1000,
|
||||
}
|
||||
|
||||
func (h HostPriorityList) Len() int {
|
||||
return len(h)
|
||||
}
|
||||
|
||||
func (h HostPriorityList) Less(i, j int) bool {
|
||||
if h[i].Score == h[j].Score {
|
||||
return h[i].Host < h[j].Host
|
||||
}
|
||||
return h[i].Score < h[j].Score
|
||||
}
|
||||
|
||||
func (h HostPriorityList) Swap(i, j int) {
|
||||
h[i], h[j] = h[j], h[i]
|
||||
}
|
||||
485
vendor/k8s.io/kubernetes/pkg/scheduler/api/zz_generated.deepcopy.go
generated
vendored
Normal file
485
vendor/k8s.io/kubernetes/pkg/scheduler/api/zz_generated.deepcopy.go
generated
vendored
Normal file
|
|
@ -0,0 +1,485 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package api
|
||||
|
||||
import (
|
||||
v1 "k8s.io/api/core/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtenderArgs) DeepCopyInto(out *ExtenderArgs) {
|
||||
*out = *in
|
||||
in.Pod.DeepCopyInto(&out.Pod)
|
||||
if in.Nodes != nil {
|
||||
in, out := &in.Nodes, &out.Nodes
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(v1.NodeList)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
if in.NodeNames != nil {
|
||||
in, out := &in.NodeNames, &out.NodeNames
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new([]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtenderArgs.
|
||||
func (in *ExtenderArgs) DeepCopy() *ExtenderArgs {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtenderArgs)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtenderBindingArgs) DeepCopyInto(out *ExtenderBindingArgs) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtenderBindingArgs.
|
||||
func (in *ExtenderBindingArgs) DeepCopy() *ExtenderBindingArgs {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtenderBindingArgs)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtenderBindingResult) DeepCopyInto(out *ExtenderBindingResult) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtenderBindingResult.
|
||||
func (in *ExtenderBindingResult) DeepCopy() *ExtenderBindingResult {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtenderBindingResult)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtenderConfig) DeepCopyInto(out *ExtenderConfig) {
|
||||
*out = *in
|
||||
if in.TLSConfig != nil {
|
||||
in, out := &in.TLSConfig, &out.TLSConfig
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(rest.TLSClientConfig)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
if in.ManagedResources != nil {
|
||||
in, out := &in.ManagedResources, &out.ManagedResources
|
||||
*out = make([]ExtenderManagedResource, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtenderConfig.
|
||||
func (in *ExtenderConfig) DeepCopy() *ExtenderConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtenderConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtenderFilterResult) DeepCopyInto(out *ExtenderFilterResult) {
|
||||
*out = *in
|
||||
if in.Nodes != nil {
|
||||
in, out := &in.Nodes, &out.Nodes
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(v1.NodeList)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
if in.NodeNames != nil {
|
||||
in, out := &in.NodeNames, &out.NodeNames
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new([]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.FailedNodes != nil {
|
||||
in, out := &in.FailedNodes, &out.FailedNodes
|
||||
*out = make(FailedNodesMap, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtenderFilterResult.
|
||||
func (in *ExtenderFilterResult) DeepCopy() *ExtenderFilterResult {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtenderFilterResult)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExtenderManagedResource) DeepCopyInto(out *ExtenderManagedResource) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtenderManagedResource.
|
||||
func (in *ExtenderManagedResource) DeepCopy() *ExtenderManagedResource {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExtenderManagedResource)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in FailedNodesMap) DeepCopyInto(out *FailedNodesMap) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(FailedNodesMap, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailedNodesMap.
|
||||
func (in FailedNodesMap) DeepCopy() FailedNodesMap {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FailedNodesMap)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HostPriority) DeepCopyInto(out *HostPriority) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostPriority.
|
||||
func (in *HostPriority) DeepCopy() *HostPriority {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HostPriority)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in HostPriorityList) DeepCopyInto(out *HostPriorityList) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(HostPriorityList, len(*in))
|
||||
copy(*out, *in)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostPriorityList.
|
||||
func (in HostPriorityList) DeepCopy() HostPriorityList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HostPriorityList)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LabelPreference) DeepCopyInto(out *LabelPreference) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LabelPreference.
|
||||
func (in *LabelPreference) DeepCopy() *LabelPreference {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LabelPreference)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LabelsPresence) DeepCopyInto(out *LabelsPresence) {
|
||||
*out = *in
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LabelsPresence.
|
||||
func (in *LabelsPresence) DeepCopy() *LabelsPresence {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LabelsPresence)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Policy) DeepCopyInto(out *Policy) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
if in.Predicates != nil {
|
||||
in, out := &in.Predicates, &out.Predicates
|
||||
*out = make([]PredicatePolicy, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Priorities != nil {
|
||||
in, out := &in.Priorities, &out.Priorities
|
||||
*out = make([]PriorityPolicy, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.ExtenderConfigs != nil {
|
||||
in, out := &in.ExtenderConfigs, &out.ExtenderConfigs
|
||||
*out = make([]ExtenderConfig, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Policy.
|
||||
func (in *Policy) DeepCopy() *Policy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Policy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Policy) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PredicateArgument) DeepCopyInto(out *PredicateArgument) {
|
||||
*out = *in
|
||||
if in.ServiceAffinity != nil {
|
||||
in, out := &in.ServiceAffinity, &out.ServiceAffinity
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(ServiceAffinity)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
if in.LabelsPresence != nil {
|
||||
in, out := &in.LabelsPresence, &out.LabelsPresence
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(LabelsPresence)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PredicateArgument.
|
||||
func (in *PredicateArgument) DeepCopy() *PredicateArgument {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PredicateArgument)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PredicatePolicy) DeepCopyInto(out *PredicatePolicy) {
|
||||
*out = *in
|
||||
if in.Argument != nil {
|
||||
in, out := &in.Argument, &out.Argument
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(PredicateArgument)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PredicatePolicy.
|
||||
func (in *PredicatePolicy) DeepCopy() *PredicatePolicy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PredicatePolicy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PriorityArgument) DeepCopyInto(out *PriorityArgument) {
|
||||
*out = *in
|
||||
if in.ServiceAntiAffinity != nil {
|
||||
in, out := &in.ServiceAntiAffinity, &out.ServiceAntiAffinity
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(ServiceAntiAffinity)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
if in.LabelPreference != nil {
|
||||
in, out := &in.LabelPreference, &out.LabelPreference
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(LabelPreference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityArgument.
|
||||
func (in *PriorityArgument) DeepCopy() *PriorityArgument {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PriorityArgument)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PriorityPolicy) DeepCopyInto(out *PriorityPolicy) {
|
||||
*out = *in
|
||||
if in.Argument != nil {
|
||||
in, out := &in.Argument, &out.Argument
|
||||
if *in == nil {
|
||||
*out = nil
|
||||
} else {
|
||||
*out = new(PriorityArgument)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityPolicy.
|
||||
func (in *PriorityPolicy) DeepCopy() *PriorityPolicy {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PriorityPolicy)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ServiceAffinity) DeepCopyInto(out *ServiceAffinity) {
|
||||
*out = *in
|
||||
if in.Labels != nil {
|
||||
in, out := &in.Labels, &out.Labels
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAffinity.
|
||||
func (in *ServiceAffinity) DeepCopy() *ServiceAffinity {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ServiceAffinity)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ServiceAntiAffinity) DeepCopyInto(out *ServiceAntiAffinity) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAntiAffinity.
|
||||
func (in *ServiceAntiAffinity) DeepCopy() *ServiceAntiAffinity {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ServiceAntiAffinity)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
497
vendor/k8s.io/kubernetes/pkg/scheduler/scheduler.go
generated
vendored
Normal file
497
vendor/k8s.io/kubernetes/pkg/scheduler/scheduler.go
generated
vendored
Normal file
|
|
@ -0,0 +1,497 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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 scheduler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
corelisters "k8s.io/client-go/listers/core/v1"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/scheduler/algorithm"
|
||||
"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
|
||||
schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
|
||||
"k8s.io/kubernetes/pkg/scheduler/core"
|
||||
"k8s.io/kubernetes/pkg/scheduler/metrics"
|
||||
"k8s.io/kubernetes/pkg/scheduler/schedulercache"
|
||||
"k8s.io/kubernetes/pkg/scheduler/util"
|
||||
"k8s.io/kubernetes/pkg/scheduler/volumebinder"
|
||||
|
||||
"github.com/golang/glog"
|
||||
)
|
||||
|
||||
// Binder knows how to write a binding.
|
||||
type Binder interface {
|
||||
Bind(binding *v1.Binding) error
|
||||
}
|
||||
|
||||
// PodConditionUpdater updates the condition of a pod based on the passed
|
||||
// PodCondition
|
||||
type PodConditionUpdater interface {
|
||||
Update(pod *v1.Pod, podCondition *v1.PodCondition) error
|
||||
}
|
||||
|
||||
// PodPreemptor has methods needed to delete a pod and to update
|
||||
// annotations of the preemptor pod.
|
||||
type PodPreemptor interface {
|
||||
GetUpdatedPod(pod *v1.Pod) (*v1.Pod, error)
|
||||
DeletePod(pod *v1.Pod) error
|
||||
SetNominatedNodeName(pod *v1.Pod, nominatedNode string) error
|
||||
RemoveNominatedNodeName(pod *v1.Pod) error
|
||||
}
|
||||
|
||||
// Scheduler watches for new unscheduled pods. It attempts to find
|
||||
// nodes that they fit on and writes bindings back to the api server.
|
||||
type Scheduler struct {
|
||||
config *Config
|
||||
}
|
||||
|
||||
// StopEverything closes the scheduler config's StopEverything channel, to shut
|
||||
// down the Scheduler.
|
||||
func (sched *Scheduler) StopEverything() {
|
||||
close(sched.config.StopEverything)
|
||||
}
|
||||
|
||||
// Configurator defines I/O, caching, and other functionality needed to
|
||||
// construct a new scheduler. An implementation of this can be seen in
|
||||
// factory.go.
|
||||
type Configurator interface {
|
||||
GetPriorityFunctionConfigs(priorityKeys sets.String) ([]algorithm.PriorityConfig, error)
|
||||
GetPriorityMetadataProducer() (algorithm.PriorityMetadataProducer, error)
|
||||
GetPredicateMetadataProducer() (algorithm.PredicateMetadataProducer, error)
|
||||
GetPredicates(predicateKeys sets.String) (map[string]algorithm.FitPredicate, error)
|
||||
GetHardPodAffinitySymmetricWeight() int32
|
||||
GetSchedulerName() string
|
||||
MakeDefaultErrorFunc(backoff *util.PodBackoff, podQueue core.SchedulingQueue) func(pod *v1.Pod, err error)
|
||||
|
||||
// Needs to be exposed for things like integration tests where we want to make fake nodes.
|
||||
GetNodeLister() corelisters.NodeLister
|
||||
GetClient() clientset.Interface
|
||||
GetScheduledPodLister() corelisters.PodLister
|
||||
|
||||
Create() (*Config, error)
|
||||
CreateFromProvider(providerName string) (*Config, error)
|
||||
CreateFromConfig(policy schedulerapi.Policy) (*Config, error)
|
||||
CreateFromKeys(predicateKeys, priorityKeys sets.String, extenders []algorithm.SchedulerExtender) (*Config, error)
|
||||
}
|
||||
|
||||
// Config is an implementation of the Scheduler's configured input data.
|
||||
// TODO over time we should make this struct a hidden implementation detail of the scheduler.
|
||||
type Config struct {
|
||||
// It is expected that changes made via SchedulerCache will be observed
|
||||
// by NodeLister and Algorithm.
|
||||
SchedulerCache schedulercache.Cache
|
||||
// Ecache is used for optimistically invalid affected cache items after
|
||||
// successfully binding a pod
|
||||
Ecache *core.EquivalenceCache
|
||||
NodeLister algorithm.NodeLister
|
||||
Algorithm algorithm.ScheduleAlgorithm
|
||||
GetBinder func(pod *v1.Pod) Binder
|
||||
// PodConditionUpdater is used only in case of scheduling errors. If we succeed
|
||||
// with scheduling, PodScheduled condition will be updated in apiserver in /bind
|
||||
// handler so that binding and setting PodCondition it is atomic.
|
||||
PodConditionUpdater PodConditionUpdater
|
||||
// PodPreemptor is used to evict pods and update pod annotations.
|
||||
PodPreemptor PodPreemptor
|
||||
|
||||
// NextPod should be a function that blocks until the next pod
|
||||
// is available. We don't use a channel for this, because scheduling
|
||||
// a pod may take some amount of time and we don't want pods to get
|
||||
// stale while they sit in a channel.
|
||||
NextPod func() *v1.Pod
|
||||
|
||||
// WaitForCacheSync waits for scheduler cache to populate.
|
||||
// It returns true if it was successful, false if the controller should shutdown.
|
||||
WaitForCacheSync func() bool
|
||||
|
||||
// Error is called if there is an error. It is passed the pod in
|
||||
// question, and the error
|
||||
Error func(*v1.Pod, error)
|
||||
|
||||
// Recorder is the EventRecorder to use
|
||||
Recorder record.EventRecorder
|
||||
|
||||
// Close this to shut down the scheduler.
|
||||
StopEverything chan struct{}
|
||||
|
||||
// VolumeBinder handles PVC/PV binding for the pod.
|
||||
VolumeBinder *volumebinder.VolumeBinder
|
||||
}
|
||||
|
||||
// NewFromConfigurator returns a new scheduler that is created entirely by the Configurator. Assumes Create() is implemented.
|
||||
// Supports intermediate Config mutation for now if you provide modifier functions which will run after Config is created.
|
||||
func NewFromConfigurator(c Configurator, modifiers ...func(c *Config)) (*Scheduler, error) {
|
||||
cfg, err := c.Create()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Mutate it if any functions were provided, changes might be required for certain types of tests (i.e. change the recorder).
|
||||
for _, modifier := range modifiers {
|
||||
modifier(cfg)
|
||||
}
|
||||
// From this point on the config is immutable to the outside.
|
||||
s := &Scheduler{
|
||||
config: cfg,
|
||||
}
|
||||
metrics.Register()
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// NewFromConfig returns a new scheduler using the provided Config.
|
||||
func NewFromConfig(config *Config) *Scheduler {
|
||||
metrics.Register()
|
||||
return &Scheduler{
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
// Run begins watching and scheduling. It waits for cache to be synced, then starts a goroutine and returns immediately.
|
||||
func (sched *Scheduler) Run() {
|
||||
if !sched.config.WaitForCacheSync() {
|
||||
return
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
|
||||
go sched.config.VolumeBinder.Run(sched.bindVolumesWorker, sched.config.StopEverything)
|
||||
}
|
||||
|
||||
go wait.Until(sched.scheduleOne, 0, sched.config.StopEverything)
|
||||
}
|
||||
|
||||
// Config return scheduler's config pointer. It is exposed for testing purposes.
|
||||
func (sched *Scheduler) Config() *Config {
|
||||
return sched.config
|
||||
}
|
||||
|
||||
// schedule implements the scheduling algorithm and returns the suggested host.
|
||||
func (sched *Scheduler) schedule(pod *v1.Pod) (string, error) {
|
||||
host, err := sched.config.Algorithm.Schedule(pod, sched.config.NodeLister)
|
||||
if err != nil {
|
||||
glog.V(1).Infof("Failed to schedule pod: %v/%v", pod.Namespace, pod.Name)
|
||||
pod = pod.DeepCopy()
|
||||
sched.config.Error(pod, err)
|
||||
sched.config.Recorder.Eventf(pod, v1.EventTypeWarning, "FailedScheduling", "%v", err)
|
||||
sched.config.PodConditionUpdater.Update(pod, &v1.PodCondition{
|
||||
Type: v1.PodScheduled,
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: v1.PodReasonUnschedulable,
|
||||
Message: err.Error(),
|
||||
})
|
||||
return "", err
|
||||
}
|
||||
return host, err
|
||||
}
|
||||
|
||||
// preempt tries to create room for a pod that has failed to schedule, by preempting lower priority pods if possible.
|
||||
// If it succeeds, it adds the name of the node where preemption has happened to the pod annotations.
|
||||
// It returns the node name and an error if any.
|
||||
func (sched *Scheduler) preempt(preemptor *v1.Pod, scheduleErr error) (string, error) {
|
||||
if !util.PodPriorityEnabled() {
|
||||
glog.V(3).Infof("Pod priority feature is not enabled. No preemption is performed.")
|
||||
return "", nil
|
||||
}
|
||||
preemptor, err := sched.config.PodPreemptor.GetUpdatedPod(preemptor)
|
||||
if err != nil {
|
||||
glog.Errorf("Error getting the updated preemptor pod object: %v", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
node, victims, nominatedPodsToClear, err := sched.config.Algorithm.Preempt(preemptor, sched.config.NodeLister, scheduleErr)
|
||||
metrics.PreemptionVictims.Set(float64(len(victims)))
|
||||
if err != nil {
|
||||
glog.Errorf("Error preempting victims to make room for %v/%v.", preemptor.Namespace, preemptor.Name)
|
||||
return "", err
|
||||
}
|
||||
var nodeName = ""
|
||||
if node != nil {
|
||||
nodeName = node.Name
|
||||
err = sched.config.PodPreemptor.SetNominatedNodeName(preemptor, nodeName)
|
||||
if err != nil {
|
||||
glog.Errorf("Error in preemption process. Cannot update pod %v annotations: %v", preemptor.Name, err)
|
||||
return "", err
|
||||
}
|
||||
for _, victim := range victims {
|
||||
if err := sched.config.PodPreemptor.DeletePod(victim); err != nil {
|
||||
glog.Errorf("Error preempting pod %v/%v: %v", victim.Namespace, victim.Name, err)
|
||||
return "", err
|
||||
}
|
||||
sched.config.Recorder.Eventf(victim, v1.EventTypeNormal, "Preempted", "by %v/%v on node %v", preemptor.Namespace, preemptor.Name, nodeName)
|
||||
}
|
||||
}
|
||||
// Clearing nominated pods should happen outside of "if node != nil". Node could
|
||||
// be nil when a pod with nominated node name is eligible to preempt again,
|
||||
// but preemption logic does not find any node for it. In that case Preempt()
|
||||
// function of generic_scheduler.go returns the pod itself for removal of the annotation.
|
||||
for _, p := range nominatedPodsToClear {
|
||||
rErr := sched.config.PodPreemptor.RemoveNominatedNodeName(p)
|
||||
if rErr != nil {
|
||||
glog.Errorf("Cannot remove nominated node annotation of pod: %v", rErr)
|
||||
// We do not return as this error is not critical.
|
||||
}
|
||||
}
|
||||
return nodeName, err
|
||||
}
|
||||
|
||||
// assumeAndBindVolumes will update the volume cache and then asynchronously bind volumes if required.
|
||||
//
|
||||
// If volume binding is required, then the bind volumes routine will update the pod to send it back through
|
||||
// the scheduler.
|
||||
//
|
||||
// Otherwise, return nil error and continue to assume the pod.
|
||||
//
|
||||
// This function modifies assumed if volume binding is required.
|
||||
func (sched *Scheduler) assumeAndBindVolumes(assumed *v1.Pod, host string) error {
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.VolumeScheduling) {
|
||||
allBound, bindingRequired, err := sched.config.VolumeBinder.Binder.AssumePodVolumes(assumed, host)
|
||||
if err != nil {
|
||||
sched.config.Error(assumed, err)
|
||||
sched.config.Recorder.Eventf(assumed, v1.EventTypeWarning, "FailedScheduling", "AssumePodVolumes failed: %v", err)
|
||||
sched.config.PodConditionUpdater.Update(assumed, &v1.PodCondition{
|
||||
Type: v1.PodScheduled,
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: "SchedulerError",
|
||||
Message: err.Error(),
|
||||
})
|
||||
return err
|
||||
}
|
||||
if !allBound {
|
||||
err = fmt.Errorf("Volume binding started, waiting for completion")
|
||||
if bindingRequired {
|
||||
if sched.config.Ecache != nil {
|
||||
invalidPredicates := sets.NewString(predicates.CheckVolumeBindingPred)
|
||||
sched.config.Ecache.InvalidateCachedPredicateItemOfAllNodes(invalidPredicates)
|
||||
}
|
||||
|
||||
// bindVolumesWorker() will update the Pod object to put it back in the scheduler queue
|
||||
sched.config.VolumeBinder.BindQueue.Add(assumed)
|
||||
} else {
|
||||
// We are just waiting for PV controller to finish binding, put it back in the
|
||||
// scheduler queue
|
||||
sched.config.Error(assumed, err)
|
||||
sched.config.Recorder.Eventf(assumed, v1.EventTypeNormal, "FailedScheduling", "%v", err)
|
||||
sched.config.PodConditionUpdater.Update(assumed, &v1.PodCondition{
|
||||
Type: v1.PodScheduled,
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: "VolumeBindingWaiting",
|
||||
})
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// bindVolumesWorker() processes pods queued in assumeAndBindVolumes() and tries to
|
||||
// make the API update for volume binding.
|
||||
// This function runs forever until the volume BindQueue is closed.
|
||||
func (sched *Scheduler) bindVolumesWorker() {
|
||||
workFunc := func() bool {
|
||||
keyObj, quit := sched.config.VolumeBinder.BindQueue.Get()
|
||||
if quit {
|
||||
return true
|
||||
}
|
||||
defer sched.config.VolumeBinder.BindQueue.Done(keyObj)
|
||||
|
||||
assumed, ok := keyObj.(*v1.Pod)
|
||||
if !ok {
|
||||
glog.V(4).Infof("Object is not a *v1.Pod")
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO: add metrics
|
||||
var reason string
|
||||
var eventType string
|
||||
|
||||
glog.V(5).Infof("Trying to bind volumes for pod \"%v/%v\"", assumed.Namespace, assumed.Name)
|
||||
|
||||
// The Pod is always sent back to the scheduler afterwards.
|
||||
err := sched.config.VolumeBinder.Binder.BindPodVolumes(assumed)
|
||||
if err != nil {
|
||||
glog.V(1).Infof("Failed to bind volumes for pod \"%v/%v\"", assumed.Namespace, assumed.Name, err)
|
||||
reason = "VolumeBindingFailed"
|
||||
eventType = v1.EventTypeWarning
|
||||
} else {
|
||||
glog.V(4).Infof("Successfully bound volumes for pod \"%v/%v\"", assumed.Namespace, assumed.Name)
|
||||
reason = "VolumeBindingWaiting"
|
||||
eventType = v1.EventTypeNormal
|
||||
err = fmt.Errorf("Volume binding started, waiting for completion")
|
||||
}
|
||||
|
||||
// Always fail scheduling regardless of binding success.
|
||||
// The Pod needs to be sent back through the scheduler to:
|
||||
// * Retry volume binding if it fails.
|
||||
// * Retry volume binding if dynamic provisioning fails.
|
||||
// * Bind the Pod to the Node once all volumes are bound.
|
||||
sched.config.Error(assumed, err)
|
||||
sched.config.Recorder.Eventf(assumed, eventType, "FailedScheduling", "%v", err)
|
||||
sched.config.PodConditionUpdater.Update(assumed, &v1.PodCondition{
|
||||
Type: v1.PodScheduled,
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: reason,
|
||||
})
|
||||
return false
|
||||
}
|
||||
|
||||
for {
|
||||
if quit := workFunc(); quit {
|
||||
glog.V(4).Infof("bindVolumesWorker shutting down")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// assume signals to the cache that a pod is already in the cache, so that binding can be asynchronous.
|
||||
// assume modifies `assumed`.
|
||||
func (sched *Scheduler) assume(assumed *v1.Pod, host string) error {
|
||||
// Optimistically assume that the binding will succeed and send it to apiserver
|
||||
// in the background.
|
||||
// If the binding fails, scheduler will release resources allocated to assumed pod
|
||||
// immediately.
|
||||
assumed.Spec.NodeName = host
|
||||
if err := sched.config.SchedulerCache.AssumePod(assumed); err != nil {
|
||||
glog.Errorf("scheduler cache AssumePod failed: %v", err)
|
||||
|
||||
// This is most probably result of a BUG in retrying logic.
|
||||
// We report an error here so that pod scheduling can be retried.
|
||||
// This relies on the fact that Error will check if the pod has been bound
|
||||
// to a node and if so will not add it back to the unscheduled pods queue
|
||||
// (otherwise this would cause an infinite loop).
|
||||
sched.config.Error(assumed, err)
|
||||
sched.config.Recorder.Eventf(assumed, v1.EventTypeWarning, "FailedScheduling", "AssumePod failed: %v", err)
|
||||
sched.config.PodConditionUpdater.Update(assumed, &v1.PodCondition{
|
||||
Type: v1.PodScheduled,
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: "SchedulerError",
|
||||
Message: err.Error(),
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// Optimistically assume that the binding will succeed, so we need to invalidate affected
|
||||
// predicates in equivalence cache.
|
||||
// If the binding fails, these invalidated item will not break anything.
|
||||
if sched.config.Ecache != nil {
|
||||
sched.config.Ecache.InvalidateCachedPredicateItemForPodAdd(assumed, host)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// bind binds a pod to a given node defined in a binding object. We expect this to run asynchronously, so we
|
||||
// handle binding metrics internally.
|
||||
func (sched *Scheduler) bind(assumed *v1.Pod, b *v1.Binding) error {
|
||||
bindingStart := time.Now()
|
||||
// If binding succeeded then PodScheduled condition will be updated in apiserver so that
|
||||
// it's atomic with setting host.
|
||||
err := sched.config.GetBinder(assumed).Bind(b)
|
||||
if err := sched.config.SchedulerCache.FinishBinding(assumed); err != nil {
|
||||
glog.Errorf("scheduler cache FinishBinding failed: %v", err)
|
||||
}
|
||||
if err != nil {
|
||||
glog.V(1).Infof("Failed to bind pod: %v/%v", assumed.Namespace, assumed.Name)
|
||||
if err := sched.config.SchedulerCache.ForgetPod(assumed); err != nil {
|
||||
glog.Errorf("scheduler cache ForgetPod failed: %v", err)
|
||||
}
|
||||
sched.config.Error(assumed, err)
|
||||
sched.config.Recorder.Eventf(assumed, v1.EventTypeWarning, "FailedScheduling", "Binding rejected: %v", err)
|
||||
sched.config.PodConditionUpdater.Update(assumed, &v1.PodCondition{
|
||||
Type: v1.PodScheduled,
|
||||
Status: v1.ConditionFalse,
|
||||
Reason: "BindingRejected",
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
metrics.BindingLatency.Observe(metrics.SinceInMicroseconds(bindingStart))
|
||||
sched.config.Recorder.Eventf(assumed, v1.EventTypeNormal, "Scheduled", "Successfully assigned %v to %v", assumed.Name, b.Target.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// scheduleOne does the entire scheduling workflow for a single pod. It is serialized on the scheduling algorithm's host fitting.
|
||||
func (sched *Scheduler) scheduleOne() {
|
||||
pod := sched.config.NextPod()
|
||||
if pod.DeletionTimestamp != nil {
|
||||
sched.config.Recorder.Eventf(pod, v1.EventTypeWarning, "FailedScheduling", "skip schedule deleting pod: %v/%v", pod.Namespace, pod.Name)
|
||||
glog.V(3).Infof("Skip schedule deleting pod: %v/%v", pod.Namespace, pod.Name)
|
||||
return
|
||||
}
|
||||
|
||||
glog.V(3).Infof("Attempting to schedule pod: %v/%v", pod.Namespace, pod.Name)
|
||||
|
||||
// Synchronously attempt to find a fit for the pod.
|
||||
start := time.Now()
|
||||
suggestedHost, err := sched.schedule(pod)
|
||||
if err != nil {
|
||||
// schedule() may have failed because the pod would not fit on any host, so we try to
|
||||
// preempt, with the expectation that the next time the pod is tried for scheduling it
|
||||
// will fit due to the preemption. It is also possible that a different pod will schedule
|
||||
// into the resources that were preempted, but this is harmless.
|
||||
if fitError, ok := err.(*core.FitError); ok {
|
||||
preemptionStartTime := time.Now()
|
||||
sched.preempt(pod, fitError)
|
||||
metrics.PreemptionAttempts.Inc()
|
||||
metrics.SchedulingAlgorithmPremptionEvaluationDuration.Observe(metrics.SinceInMicroseconds(preemptionStartTime))
|
||||
}
|
||||
return
|
||||
}
|
||||
metrics.SchedulingAlgorithmLatency.Observe(metrics.SinceInMicroseconds(start))
|
||||
// Tell the cache to assume that a pod now is running on a given node, even though it hasn't been bound yet.
|
||||
// This allows us to keep scheduling without waiting on binding to occur.
|
||||
assumedPod := pod.DeepCopy()
|
||||
|
||||
// Assume volumes first before assuming the pod.
|
||||
//
|
||||
// If no volumes need binding, then nil is returned, and continue to assume the pod.
|
||||
//
|
||||
// Otherwise, error is returned and volume binding is started asynchronously for all of the pod's volumes.
|
||||
// scheduleOne() returns immediately on error, so that it doesn't continue to assume the pod.
|
||||
//
|
||||
// After the asynchronous volume binding updates are made, it will send the pod back through the scheduler for
|
||||
// subsequent passes until all volumes are fully bound.
|
||||
//
|
||||
// This function modifies 'assumedPod' if volume binding is required.
|
||||
err = sched.assumeAndBindVolumes(assumedPod, suggestedHost)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// assume modifies `assumedPod` by setting NodeName=suggestedHost
|
||||
err = sched.assume(assumedPod, suggestedHost)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// bind the pod to its host asynchronously (we can do this b/c of the assumption step above).
|
||||
go func() {
|
||||
err := sched.bind(assumedPod, &v1.Binding{
|
||||
ObjectMeta: metav1.ObjectMeta{Namespace: assumedPod.Namespace, Name: assumedPod.Name, UID: assumedPod.UID},
|
||||
Target: v1.ObjectReference{
|
||||
Kind: "Node",
|
||||
Name: suggestedHost,
|
||||
},
|
||||
})
|
||||
metrics.E2eSchedulingLatency.Observe(metrics.SinceInMicroseconds(start))
|
||||
if err != nil {
|
||||
glog.Errorf("Internal error binding pod: (%v)", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
838
vendor/k8s.io/kubernetes/pkg/scheduler/scheduler_test.go
generated
vendored
Normal file
838
vendor/k8s.io/kubernetes/pkg/scheduler/scheduler_test.go
generated
vendored
Normal file
|
|
@ -0,0 +1,838 @@
|
|||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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 scheduler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
clientcache "k8s.io/client-go/tools/cache"
|
||||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
"k8s.io/kubernetes/pkg/controller/volume/persistentvolume"
|
||||
"k8s.io/kubernetes/pkg/scheduler/algorithm"
|
||||
"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
|
||||
"k8s.io/kubernetes/pkg/scheduler/core"
|
||||
"k8s.io/kubernetes/pkg/scheduler/schedulercache"
|
||||
schedulertesting "k8s.io/kubernetes/pkg/scheduler/testing"
|
||||
"k8s.io/kubernetes/pkg/scheduler/util"
|
||||
"k8s.io/kubernetes/pkg/scheduler/volumebinder"
|
||||
)
|
||||
|
||||
type fakeBinder struct {
|
||||
b func(binding *v1.Binding) error
|
||||
}
|
||||
|
||||
func (fb fakeBinder) Bind(binding *v1.Binding) error { return fb.b(binding) }
|
||||
|
||||
type fakePodConditionUpdater struct{}
|
||||
|
||||
func (fc fakePodConditionUpdater) Update(pod *v1.Pod, podCondition *v1.PodCondition) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type fakePodPreemptor struct{}
|
||||
|
||||
func (fp fakePodPreemptor) GetUpdatedPod(pod *v1.Pod) (*v1.Pod, error) {
|
||||
return pod, nil
|
||||
}
|
||||
|
||||
func (fp fakePodPreemptor) DeletePod(pod *v1.Pod) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fp fakePodPreemptor) SetNominatedNodeName(pod *v1.Pod, nomNodeName string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (fp fakePodPreemptor) RemoveNominatedNodeName(pod *v1.Pod) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func podWithID(id, desiredHost string) *v1.Pod {
|
||||
return &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: id,
|
||||
UID: types.UID(id),
|
||||
SelfLink: util.Test.SelfLink(string(v1.ResourcePods), id),
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
NodeName: desiredHost,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func deletingPod(id string) *v1.Pod {
|
||||
deletionTimestamp := metav1.Now()
|
||||
return &v1.Pod{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: id,
|
||||
UID: types.UID(id),
|
||||
SelfLink: util.Test.SelfLink(string(v1.ResourcePods), id),
|
||||
DeletionTimestamp: &deletionTimestamp,
|
||||
},
|
||||
Spec: v1.PodSpec{
|
||||
NodeName: "",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func podWithPort(id, desiredHost string, port int) *v1.Pod {
|
||||
pod := podWithID(id, desiredHost)
|
||||
pod.Spec.Containers = []v1.Container{
|
||||
{Name: "ctr", Ports: []v1.ContainerPort{{HostPort: int32(port)}}},
|
||||
}
|
||||
return pod
|
||||
}
|
||||
|
||||
func podWithResources(id, desiredHost string, limits v1.ResourceList, requests v1.ResourceList) *v1.Pod {
|
||||
pod := podWithID(id, desiredHost)
|
||||
pod.Spec.Containers = []v1.Container{
|
||||
{Name: "ctr", Resources: v1.ResourceRequirements{Limits: limits, Requests: requests}},
|
||||
}
|
||||
return pod
|
||||
}
|
||||
|
||||
type mockScheduler struct {
|
||||
machine string
|
||||
err error
|
||||
}
|
||||
|
||||
func (es mockScheduler) Schedule(pod *v1.Pod, ml algorithm.NodeLister) (string, error) {
|
||||
return es.machine, es.err
|
||||
}
|
||||
|
||||
func (es mockScheduler) Predicates() map[string]algorithm.FitPredicate {
|
||||
return nil
|
||||
}
|
||||
func (es mockScheduler) Prioritizers() []algorithm.PriorityConfig {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (es mockScheduler) Preempt(pod *v1.Pod, nodeLister algorithm.NodeLister, scheduleErr error) (*v1.Node, []*v1.Pod, []*v1.Pod, error) {
|
||||
return nil, nil, nil, nil
|
||||
}
|
||||
|
||||
func TestScheduler(t *testing.T) {
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
eventBroadcaster.StartLogging(t.Logf).Stop()
|
||||
errS := errors.New("scheduler")
|
||||
errB := errors.New("binder")
|
||||
testNode := v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "machine1", UID: types.UID("machine1")}}
|
||||
|
||||
table := []struct {
|
||||
injectBindError error
|
||||
sendPod *v1.Pod
|
||||
algo algorithm.ScheduleAlgorithm
|
||||
expectErrorPod *v1.Pod
|
||||
expectForgetPod *v1.Pod
|
||||
expectAssumedPod *v1.Pod
|
||||
expectError error
|
||||
expectBind *v1.Binding
|
||||
eventReason string
|
||||
}{
|
||||
{
|
||||
sendPod: podWithID("foo", ""),
|
||||
algo: mockScheduler{testNode.Name, nil},
|
||||
expectBind: &v1.Binding{ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: types.UID("foo")}, Target: v1.ObjectReference{Kind: "Node", Name: testNode.Name}},
|
||||
expectAssumedPod: podWithID("foo", testNode.Name),
|
||||
eventReason: "Scheduled",
|
||||
}, {
|
||||
sendPod: podWithID("foo", ""),
|
||||
algo: mockScheduler{testNode.Name, errS},
|
||||
expectError: errS,
|
||||
expectErrorPod: podWithID("foo", ""),
|
||||
eventReason: "FailedScheduling",
|
||||
}, {
|
||||
sendPod: podWithID("foo", ""),
|
||||
algo: mockScheduler{testNode.Name, nil},
|
||||
expectBind: &v1.Binding{ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: types.UID("foo")}, Target: v1.ObjectReference{Kind: "Node", Name: testNode.Name}},
|
||||
expectAssumedPod: podWithID("foo", testNode.Name),
|
||||
injectBindError: errB,
|
||||
expectError: errB,
|
||||
expectErrorPod: podWithID("foo", testNode.Name),
|
||||
expectForgetPod: podWithID("foo", testNode.Name),
|
||||
eventReason: "FailedScheduling",
|
||||
}, {
|
||||
sendPod: deletingPod("foo"),
|
||||
algo: mockScheduler{"", nil},
|
||||
eventReason: "FailedScheduling",
|
||||
},
|
||||
}
|
||||
|
||||
for i, item := range table {
|
||||
var gotError error
|
||||
var gotPod *v1.Pod
|
||||
var gotForgetPod *v1.Pod
|
||||
var gotAssumedPod *v1.Pod
|
||||
var gotBinding *v1.Binding
|
||||
configurator := &FakeConfigurator{
|
||||
Config: &Config{
|
||||
SchedulerCache: &schedulertesting.FakeCache{
|
||||
ForgetFunc: func(pod *v1.Pod) {
|
||||
gotForgetPod = pod
|
||||
},
|
||||
AssumeFunc: func(pod *v1.Pod) {
|
||||
gotAssumedPod = pod
|
||||
},
|
||||
},
|
||||
NodeLister: schedulertesting.FakeNodeLister(
|
||||
[]*v1.Node{&testNode},
|
||||
),
|
||||
Algorithm: item.algo,
|
||||
GetBinder: func(pod *v1.Pod) Binder {
|
||||
return fakeBinder{func(b *v1.Binding) error {
|
||||
gotBinding = b
|
||||
return item.injectBindError
|
||||
}}
|
||||
},
|
||||
PodConditionUpdater: fakePodConditionUpdater{},
|
||||
Error: func(p *v1.Pod, err error) {
|
||||
gotPod = p
|
||||
gotError = err
|
||||
},
|
||||
NextPod: func() *v1.Pod {
|
||||
return item.sendPod
|
||||
},
|
||||
Recorder: eventBroadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: "scheduler"}),
|
||||
VolumeBinder: volumebinder.NewFakeVolumeBinder(&persistentvolume.FakeVolumeBinderConfig{AllBound: true}),
|
||||
},
|
||||
}
|
||||
|
||||
s, _ := NewFromConfigurator(configurator, nil...)
|
||||
called := make(chan struct{})
|
||||
events := eventBroadcaster.StartEventWatcher(func(e *v1.Event) {
|
||||
if e, a := item.eventReason, e.Reason; e != a {
|
||||
t.Errorf("%v: expected %v, got %v", i, e, a)
|
||||
}
|
||||
close(called)
|
||||
})
|
||||
s.scheduleOne()
|
||||
<-called
|
||||
if e, a := item.expectAssumedPod, gotAssumedPod; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%v: assumed pod: wanted %v, got %v", i, e, a)
|
||||
}
|
||||
if e, a := item.expectErrorPod, gotPod; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%v: error pod: wanted %v, got %v", i, e, a)
|
||||
}
|
||||
if e, a := item.expectForgetPod, gotForgetPod; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%v: forget pod: wanted %v, got %v", i, e, a)
|
||||
}
|
||||
if e, a := item.expectError, gotError; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%v: error: wanted %v, got %v", i, e, a)
|
||||
}
|
||||
if e, a := item.expectBind, gotBinding; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%v: error: %s", i, diff.ObjectDiff(e, a))
|
||||
}
|
||||
events.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
func TestSchedulerNoPhantomPodAfterExpire(t *testing.T) {
|
||||
stop := make(chan struct{})
|
||||
defer close(stop)
|
||||
queuedPodStore := clientcache.NewFIFO(clientcache.MetaNamespaceKeyFunc)
|
||||
scache := schedulercache.New(100*time.Millisecond, stop)
|
||||
pod := podWithPort("pod.Name", "", 8080)
|
||||
node := v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "machine1", UID: types.UID("machine1")}}
|
||||
scache.AddNode(&node)
|
||||
nodeLister := schedulertesting.FakeNodeLister([]*v1.Node{&node})
|
||||
predicateMap := map[string]algorithm.FitPredicate{"PodFitsHostPorts": predicates.PodFitsHostPorts}
|
||||
scheduler, bindingChan, _ := setupTestSchedulerWithOnePodOnNode(t, queuedPodStore, scache, nodeLister, predicateMap, pod, &node)
|
||||
|
||||
waitPodExpireChan := make(chan struct{})
|
||||
timeout := make(chan struct{})
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-timeout:
|
||||
return
|
||||
default:
|
||||
}
|
||||
pods, err := scache.List(labels.Everything())
|
||||
if err != nil {
|
||||
t.Fatalf("cache.List failed: %v", err)
|
||||
}
|
||||
if len(pods) == 0 {
|
||||
close(waitPodExpireChan)
|
||||
return
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
}()
|
||||
// waiting for the assumed pod to expire
|
||||
select {
|
||||
case <-waitPodExpireChan:
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
close(timeout)
|
||||
t.Fatalf("timeout timeout in waiting pod expire after %v", wait.ForeverTestTimeout)
|
||||
}
|
||||
|
||||
// We use conflicted pod ports to incur fit predicate failure if first pod not removed.
|
||||
secondPod := podWithPort("bar", "", 8080)
|
||||
queuedPodStore.Add(secondPod)
|
||||
scheduler.scheduleOne()
|
||||
select {
|
||||
case b := <-bindingChan:
|
||||
expectBinding := &v1.Binding{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "bar", UID: types.UID("bar")},
|
||||
Target: v1.ObjectReference{Kind: "Node", Name: node.Name},
|
||||
}
|
||||
if !reflect.DeepEqual(expectBinding, b) {
|
||||
t.Errorf("binding want=%v, get=%v", expectBinding, b)
|
||||
}
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Fatalf("timeout in binding after %v", wait.ForeverTestTimeout)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSchedulerNoPhantomPodAfterDelete(t *testing.T) {
|
||||
stop := make(chan struct{})
|
||||
defer close(stop)
|
||||
queuedPodStore := clientcache.NewFIFO(clientcache.MetaNamespaceKeyFunc)
|
||||
scache := schedulercache.New(10*time.Minute, stop)
|
||||
firstPod := podWithPort("pod.Name", "", 8080)
|
||||
node := v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "machine1", UID: types.UID("machine1")}}
|
||||
scache.AddNode(&node)
|
||||
nodeLister := schedulertesting.FakeNodeLister([]*v1.Node{&node})
|
||||
predicateMap := map[string]algorithm.FitPredicate{"PodFitsHostPorts": predicates.PodFitsHostPorts}
|
||||
scheduler, bindingChan, errChan := setupTestSchedulerWithOnePodOnNode(t, queuedPodStore, scache, nodeLister, predicateMap, firstPod, &node)
|
||||
|
||||
// We use conflicted pod ports to incur fit predicate failure.
|
||||
secondPod := podWithPort("bar", "", 8080)
|
||||
queuedPodStore.Add(secondPod)
|
||||
// queuedPodStore: [bar:8080]
|
||||
// cache: [(assumed)foo:8080]
|
||||
|
||||
scheduler.scheduleOne()
|
||||
select {
|
||||
case err := <-errChan:
|
||||
expectErr := &core.FitError{
|
||||
Pod: secondPod,
|
||||
NumAllNodes: 1,
|
||||
FailedPredicates: core.FailedPredicateMap{node.Name: []algorithm.PredicateFailureReason{predicates.ErrPodNotFitsHostPorts}},
|
||||
}
|
||||
if !reflect.DeepEqual(expectErr, err) {
|
||||
t.Errorf("err want=%v, get=%v", expectErr, err)
|
||||
}
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Fatalf("timeout in fitting after %v", wait.ForeverTestTimeout)
|
||||
}
|
||||
|
||||
// We mimic the workflow of cache behavior when a pod is removed by user.
|
||||
// Note: if the schedulercache timeout would be super short, the first pod would expire
|
||||
// and would be removed itself (without any explicit actions on schedulercache). Even in that case,
|
||||
// explicitly AddPod will as well correct the behavior.
|
||||
firstPod.Spec.NodeName = node.Name
|
||||
if err := scache.AddPod(firstPod); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if err := scache.RemovePod(firstPod); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
queuedPodStore.Add(secondPod)
|
||||
scheduler.scheduleOne()
|
||||
select {
|
||||
case b := <-bindingChan:
|
||||
expectBinding := &v1.Binding{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "bar", UID: types.UID("bar")},
|
||||
Target: v1.ObjectReference{Kind: "Node", Name: node.Name},
|
||||
}
|
||||
if !reflect.DeepEqual(expectBinding, b) {
|
||||
t.Errorf("binding want=%v, get=%v", expectBinding, b)
|
||||
}
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Fatalf("timeout in binding after %v", wait.ForeverTestTimeout)
|
||||
}
|
||||
}
|
||||
|
||||
// Scheduler should preserve predicate constraint even if binding was longer
|
||||
// than cache ttl
|
||||
func TestSchedulerErrorWithLongBinding(t *testing.T) {
|
||||
stop := make(chan struct{})
|
||||
defer close(stop)
|
||||
|
||||
firstPod := podWithPort("foo", "", 8080)
|
||||
conflictPod := podWithPort("bar", "", 8080)
|
||||
pods := map[string]*v1.Pod{firstPod.Name: firstPod, conflictPod.Name: conflictPod}
|
||||
for _, test := range []struct {
|
||||
Expected map[string]bool
|
||||
CacheTTL time.Duration
|
||||
BindingDuration time.Duration
|
||||
}{
|
||||
{
|
||||
Expected: map[string]bool{firstPod.Name: true},
|
||||
CacheTTL: 100 * time.Millisecond,
|
||||
BindingDuration: 300 * time.Millisecond,
|
||||
},
|
||||
{
|
||||
Expected: map[string]bool{firstPod.Name: true},
|
||||
CacheTTL: 10 * time.Second,
|
||||
BindingDuration: 300 * time.Millisecond,
|
||||
},
|
||||
} {
|
||||
queuedPodStore := clientcache.NewFIFO(clientcache.MetaNamespaceKeyFunc)
|
||||
scache := schedulercache.New(test.CacheTTL, stop)
|
||||
|
||||
node := v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "machine1", UID: types.UID("machine1")}}
|
||||
scache.AddNode(&node)
|
||||
|
||||
nodeLister := schedulertesting.FakeNodeLister([]*v1.Node{&node})
|
||||
predicateMap := map[string]algorithm.FitPredicate{"PodFitsHostPorts": predicates.PodFitsHostPorts}
|
||||
|
||||
scheduler, bindingChan := setupTestSchedulerLongBindingWithRetry(
|
||||
queuedPodStore, scache, nodeLister, predicateMap, stop, test.BindingDuration)
|
||||
scheduler.Run()
|
||||
queuedPodStore.Add(firstPod)
|
||||
queuedPodStore.Add(conflictPod)
|
||||
|
||||
resultBindings := map[string]bool{}
|
||||
waitChan := time.After(5 * time.Second)
|
||||
for finished := false; !finished; {
|
||||
select {
|
||||
case b := <-bindingChan:
|
||||
resultBindings[b.Name] = true
|
||||
p := pods[b.Name]
|
||||
p.Spec.NodeName = b.Target.Name
|
||||
scache.AddPod(p)
|
||||
case <-waitChan:
|
||||
finished = true
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(resultBindings, test.Expected) {
|
||||
t.Errorf("Result binding are not equal to expected. %v != %v", resultBindings, test.Expected)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// queuedPodStore: pods queued before processing.
|
||||
// cache: scheduler cache that might contain assumed pods.
|
||||
func setupTestSchedulerWithOnePodOnNode(t *testing.T, queuedPodStore *clientcache.FIFO, scache schedulercache.Cache,
|
||||
nodeLister schedulertesting.FakeNodeLister, predicateMap map[string]algorithm.FitPredicate, pod *v1.Pod, node *v1.Node) (*Scheduler, chan *v1.Binding, chan error) {
|
||||
|
||||
scheduler, bindingChan, errChan := setupTestScheduler(queuedPodStore, scache, nodeLister, predicateMap, nil)
|
||||
|
||||
queuedPodStore.Add(pod)
|
||||
// queuedPodStore: [foo:8080]
|
||||
// cache: []
|
||||
|
||||
scheduler.scheduleOne()
|
||||
// queuedPodStore: []
|
||||
// cache: [(assumed)foo:8080]
|
||||
|
||||
select {
|
||||
case b := <-bindingChan:
|
||||
expectBinding := &v1.Binding{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: pod.Name, UID: types.UID(pod.Name)},
|
||||
Target: v1.ObjectReference{Kind: "Node", Name: node.Name},
|
||||
}
|
||||
if !reflect.DeepEqual(expectBinding, b) {
|
||||
t.Errorf("binding want=%v, get=%v", expectBinding, b)
|
||||
}
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Fatalf("timeout after %v", wait.ForeverTestTimeout)
|
||||
}
|
||||
return scheduler, bindingChan, errChan
|
||||
}
|
||||
|
||||
func TestSchedulerFailedSchedulingReasons(t *testing.T) {
|
||||
stop := make(chan struct{})
|
||||
defer close(stop)
|
||||
queuedPodStore := clientcache.NewFIFO(clientcache.MetaNamespaceKeyFunc)
|
||||
scache := schedulercache.New(10*time.Minute, stop)
|
||||
|
||||
// Design the baseline for the pods, and we will make nodes that dont fit it later.
|
||||
var cpu = int64(4)
|
||||
var mem = int64(500)
|
||||
podWithTooBigResourceRequests := podWithResources("bar", "", v1.ResourceList{
|
||||
v1.ResourceCPU: *(resource.NewQuantity(cpu, resource.DecimalSI)),
|
||||
v1.ResourceMemory: *(resource.NewQuantity(mem, resource.DecimalSI)),
|
||||
}, v1.ResourceList{
|
||||
v1.ResourceCPU: *(resource.NewQuantity(cpu, resource.DecimalSI)),
|
||||
v1.ResourceMemory: *(resource.NewQuantity(mem, resource.DecimalSI)),
|
||||
})
|
||||
|
||||
// create several nodes which cannot schedule the above pod
|
||||
nodes := []*v1.Node{}
|
||||
for i := 0; i < 100; i++ {
|
||||
uid := fmt.Sprintf("machine%v", i)
|
||||
node := v1.Node{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: uid, UID: types.UID(uid)},
|
||||
Status: v1.NodeStatus{
|
||||
Capacity: v1.ResourceList{
|
||||
v1.ResourceCPU: *(resource.NewQuantity(cpu/2, resource.DecimalSI)),
|
||||
v1.ResourceMemory: *(resource.NewQuantity(mem/5, resource.DecimalSI)),
|
||||
v1.ResourcePods: *(resource.NewQuantity(10, resource.DecimalSI)),
|
||||
},
|
||||
Allocatable: v1.ResourceList{
|
||||
v1.ResourceCPU: *(resource.NewQuantity(cpu/2, resource.DecimalSI)),
|
||||
v1.ResourceMemory: *(resource.NewQuantity(mem/5, resource.DecimalSI)),
|
||||
v1.ResourcePods: *(resource.NewQuantity(10, resource.DecimalSI)),
|
||||
}},
|
||||
}
|
||||
scache.AddNode(&node)
|
||||
nodes = append(nodes, &node)
|
||||
}
|
||||
nodeLister := schedulertesting.FakeNodeLister(nodes)
|
||||
predicateMap := map[string]algorithm.FitPredicate{
|
||||
"PodFitsResources": predicates.PodFitsResources,
|
||||
}
|
||||
|
||||
// Create expected failure reasons for all the nodes. Hopefully they will get rolled up into a non-spammy summary.
|
||||
failedPredicatesMap := core.FailedPredicateMap{}
|
||||
for _, node := range nodes {
|
||||
failedPredicatesMap[node.Name] = []algorithm.PredicateFailureReason{
|
||||
predicates.NewInsufficientResourceError(v1.ResourceCPU, 4000, 0, 2000),
|
||||
predicates.NewInsufficientResourceError(v1.ResourceMemory, 500, 0, 100),
|
||||
}
|
||||
}
|
||||
scheduler, _, errChan := setupTestScheduler(queuedPodStore, scache, nodeLister, predicateMap, nil)
|
||||
|
||||
queuedPodStore.Add(podWithTooBigResourceRequests)
|
||||
scheduler.scheduleOne()
|
||||
select {
|
||||
case err := <-errChan:
|
||||
expectErr := &core.FitError{
|
||||
Pod: podWithTooBigResourceRequests,
|
||||
NumAllNodes: len(nodes),
|
||||
FailedPredicates: failedPredicatesMap,
|
||||
}
|
||||
if len(fmt.Sprint(expectErr)) > 150 {
|
||||
t.Errorf("message is too spammy ! %v ", len(fmt.Sprint(expectErr)))
|
||||
}
|
||||
if !reflect.DeepEqual(expectErr, err) {
|
||||
t.Errorf("\n err \nWANT=%+v,\nGOT=%+v", expectErr, err)
|
||||
}
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Fatalf("timeout after %v", wait.ForeverTestTimeout)
|
||||
}
|
||||
}
|
||||
|
||||
// queuedPodStore: pods queued before processing.
|
||||
// scache: scheduler cache that might contain assumed pods.
|
||||
func setupTestScheduler(queuedPodStore *clientcache.FIFO, scache schedulercache.Cache, nodeLister schedulertesting.FakeNodeLister, predicateMap map[string]algorithm.FitPredicate, recorder record.EventRecorder) (*Scheduler, chan *v1.Binding, chan error) {
|
||||
algo := core.NewGenericScheduler(
|
||||
scache,
|
||||
nil,
|
||||
nil,
|
||||
predicateMap,
|
||||
algorithm.EmptyPredicateMetadataProducer,
|
||||
[]algorithm.PriorityConfig{},
|
||||
algorithm.EmptyPriorityMetadataProducer,
|
||||
[]algorithm.SchedulerExtender{},
|
||||
nil,
|
||||
schedulertesting.FakePersistentVolumeClaimLister{},
|
||||
false)
|
||||
bindingChan := make(chan *v1.Binding, 1)
|
||||
errChan := make(chan error, 1)
|
||||
configurator := &FakeConfigurator{
|
||||
Config: &Config{
|
||||
SchedulerCache: scache,
|
||||
NodeLister: nodeLister,
|
||||
Algorithm: algo,
|
||||
GetBinder: func(pod *v1.Pod) Binder {
|
||||
return fakeBinder{func(b *v1.Binding) error {
|
||||
bindingChan <- b
|
||||
return nil
|
||||
}}
|
||||
},
|
||||
NextPod: func() *v1.Pod {
|
||||
return clientcache.Pop(queuedPodStore).(*v1.Pod)
|
||||
},
|
||||
Error: func(p *v1.Pod, err error) {
|
||||
errChan <- err
|
||||
},
|
||||
Recorder: &record.FakeRecorder{},
|
||||
PodConditionUpdater: fakePodConditionUpdater{},
|
||||
PodPreemptor: fakePodPreemptor{},
|
||||
VolumeBinder: volumebinder.NewFakeVolumeBinder(&persistentvolume.FakeVolumeBinderConfig{AllBound: true}),
|
||||
},
|
||||
}
|
||||
|
||||
if recorder != nil {
|
||||
configurator.Config.Recorder = recorder
|
||||
}
|
||||
|
||||
sched, _ := NewFromConfigurator(configurator, nil...)
|
||||
|
||||
return sched, bindingChan, errChan
|
||||
}
|
||||
|
||||
func setupTestSchedulerLongBindingWithRetry(queuedPodStore *clientcache.FIFO, scache schedulercache.Cache, nodeLister schedulertesting.FakeNodeLister, predicateMap map[string]algorithm.FitPredicate, stop chan struct{}, bindingTime time.Duration) (*Scheduler, chan *v1.Binding) {
|
||||
algo := core.NewGenericScheduler(
|
||||
scache,
|
||||
nil,
|
||||
nil,
|
||||
predicateMap,
|
||||
algorithm.EmptyPredicateMetadataProducer,
|
||||
[]algorithm.PriorityConfig{},
|
||||
algorithm.EmptyPriorityMetadataProducer,
|
||||
[]algorithm.SchedulerExtender{},
|
||||
nil,
|
||||
schedulertesting.FakePersistentVolumeClaimLister{},
|
||||
false)
|
||||
bindingChan := make(chan *v1.Binding, 2)
|
||||
configurator := &FakeConfigurator{
|
||||
Config: &Config{
|
||||
SchedulerCache: scache,
|
||||
NodeLister: nodeLister,
|
||||
Algorithm: algo,
|
||||
GetBinder: func(pod *v1.Pod) Binder {
|
||||
return fakeBinder{func(b *v1.Binding) error {
|
||||
time.Sleep(bindingTime)
|
||||
bindingChan <- b
|
||||
return nil
|
||||
}}
|
||||
},
|
||||
WaitForCacheSync: func() bool {
|
||||
return true
|
||||
},
|
||||
NextPod: func() *v1.Pod {
|
||||
return clientcache.Pop(queuedPodStore).(*v1.Pod)
|
||||
},
|
||||
Error: func(p *v1.Pod, err error) {
|
||||
queuedPodStore.AddIfNotPresent(p)
|
||||
},
|
||||
Recorder: &record.FakeRecorder{},
|
||||
PodConditionUpdater: fakePodConditionUpdater{},
|
||||
PodPreemptor: fakePodPreemptor{},
|
||||
StopEverything: stop,
|
||||
VolumeBinder: volumebinder.NewFakeVolumeBinder(&persistentvolume.FakeVolumeBinderConfig{AllBound: true}),
|
||||
},
|
||||
}
|
||||
|
||||
sched, _ := NewFromConfigurator(configurator, nil...)
|
||||
|
||||
return sched, bindingChan
|
||||
}
|
||||
|
||||
func setupTestSchedulerWithVolumeBinding(fakeVolumeBinder *volumebinder.VolumeBinder, stop <-chan struct{}, broadcaster record.EventBroadcaster) (*Scheduler, chan *v1.Binding, chan error) {
|
||||
testNode := v1.Node{ObjectMeta: metav1.ObjectMeta{Name: "machine1", UID: types.UID("machine1")}}
|
||||
nodeLister := schedulertesting.FakeNodeLister([]*v1.Node{&testNode})
|
||||
queuedPodStore := clientcache.NewFIFO(clientcache.MetaNamespaceKeyFunc)
|
||||
queuedPodStore.Add(podWithID("foo", ""))
|
||||
scache := schedulercache.New(10*time.Minute, stop)
|
||||
scache.AddNode(&testNode)
|
||||
|
||||
predicateMap := map[string]algorithm.FitPredicate{
|
||||
predicates.CheckVolumeBindingPred: predicates.NewVolumeBindingPredicate(fakeVolumeBinder),
|
||||
}
|
||||
|
||||
recorder := broadcaster.NewRecorder(legacyscheme.Scheme, v1.EventSource{Component: "scheduler"})
|
||||
s, bindingChan, errChan := setupTestScheduler(queuedPodStore, scache, nodeLister, predicateMap, recorder)
|
||||
s.config.VolumeBinder = fakeVolumeBinder
|
||||
return s, bindingChan, errChan
|
||||
}
|
||||
|
||||
// This is a workaround because golint complains that errors cannot
|
||||
// end with punctuation. However, the real predicate error message does
|
||||
// end with a period.
|
||||
func makePredicateError(failReason string) error {
|
||||
s := fmt.Sprintf("0/1 nodes are available: %v.", failReason)
|
||||
return fmt.Errorf(s)
|
||||
}
|
||||
|
||||
func TestSchedulerWithVolumeBinding(t *testing.T) {
|
||||
order := []string{predicates.CheckVolumeBindingPred, predicates.GeneralPred}
|
||||
predicates.SetPredicatesOrdering(order)
|
||||
findErr := fmt.Errorf("find err")
|
||||
assumeErr := fmt.Errorf("assume err")
|
||||
bindErr := fmt.Errorf("bind err")
|
||||
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
eventBroadcaster.StartLogging(t.Logf).Stop()
|
||||
|
||||
// This can be small because we wait for pod to finish scheduling first
|
||||
chanTimeout := 2 * time.Second
|
||||
|
||||
utilfeature.DefaultFeatureGate.Set("VolumeScheduling=true")
|
||||
defer utilfeature.DefaultFeatureGate.Set("VolumeScheduling=false")
|
||||
|
||||
table := map[string]struct {
|
||||
expectError error
|
||||
expectPodBind *v1.Binding
|
||||
expectAssumeCalled bool
|
||||
expectBindCalled bool
|
||||
eventReason string
|
||||
volumeBinderConfig *persistentvolume.FakeVolumeBinderConfig
|
||||
}{
|
||||
"all-bound": {
|
||||
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
|
||||
AllBound: true,
|
||||
FindUnboundSatsified: true,
|
||||
FindBoundSatsified: true,
|
||||
},
|
||||
expectAssumeCalled: true,
|
||||
expectPodBind: &v1.Binding{ObjectMeta: metav1.ObjectMeta{Name: "foo", UID: types.UID("foo")}, Target: v1.ObjectReference{Kind: "Node", Name: "machine1"}},
|
||||
|
||||
eventReason: "Scheduled",
|
||||
},
|
||||
"bound,invalid-pv-affinity": {
|
||||
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
|
||||
AllBound: true,
|
||||
FindUnboundSatsified: true,
|
||||
FindBoundSatsified: false,
|
||||
},
|
||||
eventReason: "FailedScheduling",
|
||||
expectError: makePredicateError("1 node(s) had volume node affinity conflict"),
|
||||
},
|
||||
"unbound,no-matches": {
|
||||
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
|
||||
FindUnboundSatsified: false,
|
||||
FindBoundSatsified: true,
|
||||
},
|
||||
eventReason: "FailedScheduling",
|
||||
expectError: makePredicateError("1 node(s) didn't find available persistent volumes to bind"),
|
||||
},
|
||||
"bound-and-unbound-unsatisfied": {
|
||||
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
|
||||
FindUnboundSatsified: false,
|
||||
FindBoundSatsified: false,
|
||||
},
|
||||
eventReason: "FailedScheduling",
|
||||
expectError: makePredicateError("1 node(s) didn't find available persistent volumes to bind, 1 node(s) had volume node affinity conflict"),
|
||||
},
|
||||
"unbound,found-matches": {
|
||||
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
|
||||
FindUnboundSatsified: true,
|
||||
FindBoundSatsified: true,
|
||||
AssumeBindingRequired: true,
|
||||
},
|
||||
expectAssumeCalled: true,
|
||||
expectBindCalled: true,
|
||||
eventReason: "FailedScheduling",
|
||||
expectError: fmt.Errorf("Volume binding started, waiting for completion"),
|
||||
},
|
||||
"unbound,found-matches,already-bound": {
|
||||
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
|
||||
FindUnboundSatsified: true,
|
||||
FindBoundSatsified: true,
|
||||
AssumeBindingRequired: false,
|
||||
},
|
||||
expectAssumeCalled: true,
|
||||
expectBindCalled: false,
|
||||
eventReason: "FailedScheduling",
|
||||
expectError: fmt.Errorf("Volume binding started, waiting for completion"),
|
||||
},
|
||||
"predicate-error": {
|
||||
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
|
||||
FindErr: findErr,
|
||||
},
|
||||
eventReason: "FailedScheduling",
|
||||
expectError: findErr,
|
||||
},
|
||||
"assume-error": {
|
||||
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
|
||||
FindUnboundSatsified: true,
|
||||
FindBoundSatsified: true,
|
||||
AssumeErr: assumeErr,
|
||||
},
|
||||
expectAssumeCalled: true,
|
||||
eventReason: "FailedScheduling",
|
||||
expectError: assumeErr,
|
||||
},
|
||||
"bind-error": {
|
||||
volumeBinderConfig: &persistentvolume.FakeVolumeBinderConfig{
|
||||
FindUnboundSatsified: true,
|
||||
FindBoundSatsified: true,
|
||||
AssumeBindingRequired: true,
|
||||
BindErr: bindErr,
|
||||
},
|
||||
expectAssumeCalled: true,
|
||||
expectBindCalled: true,
|
||||
eventReason: "FailedScheduling",
|
||||
expectError: bindErr,
|
||||
},
|
||||
}
|
||||
|
||||
for name, item := range table {
|
||||
stop := make(chan struct{})
|
||||
fakeVolumeBinder := volumebinder.NewFakeVolumeBinder(item.volumeBinderConfig)
|
||||
internalBinder, ok := fakeVolumeBinder.Binder.(*persistentvolume.FakeVolumeBinder)
|
||||
if !ok {
|
||||
t.Fatalf("Failed to get fake volume binder")
|
||||
}
|
||||
s, bindingChan, errChan := setupTestSchedulerWithVolumeBinding(fakeVolumeBinder, stop, eventBroadcaster)
|
||||
|
||||
eventChan := make(chan struct{})
|
||||
events := eventBroadcaster.StartEventWatcher(func(e *v1.Event) {
|
||||
if e, a := item.eventReason, e.Reason; e != a {
|
||||
t.Errorf("%v: expected %v, got %v", name, e, a)
|
||||
}
|
||||
close(eventChan)
|
||||
})
|
||||
|
||||
go fakeVolumeBinder.Run(s.bindVolumesWorker, stop)
|
||||
|
||||
s.scheduleOne()
|
||||
|
||||
// Wait for pod to succeed or fail scheduling
|
||||
select {
|
||||
case <-eventChan:
|
||||
case <-time.After(wait.ForeverTestTimeout):
|
||||
t.Fatalf("%v: scheduling timeout after %v", name, wait.ForeverTestTimeout)
|
||||
}
|
||||
|
||||
events.Stop()
|
||||
|
||||
// Wait for scheduling to return an error
|
||||
select {
|
||||
case err := <-errChan:
|
||||
if item.expectError == nil || !reflect.DeepEqual(item.expectError.Error(), err.Error()) {
|
||||
t.Errorf("%v: \n err \nWANT=%+v,\nGOT=%+v", name, item.expectError, err)
|
||||
}
|
||||
case <-time.After(chanTimeout):
|
||||
if item.expectError != nil {
|
||||
t.Errorf("%v: did not receive error after %v", name, chanTimeout)
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for pod to succeed binding
|
||||
select {
|
||||
case b := <-bindingChan:
|
||||
if !reflect.DeepEqual(item.expectPodBind, b) {
|
||||
t.Errorf("%v: \n err \nWANT=%+v,\nGOT=%+v", name, item.expectPodBind, b)
|
||||
}
|
||||
case <-time.After(chanTimeout):
|
||||
if item.expectPodBind != nil {
|
||||
t.Errorf("%v: did not receive pod binding after %v", name, chanTimeout)
|
||||
}
|
||||
}
|
||||
|
||||
if item.expectAssumeCalled != internalBinder.AssumeCalled {
|
||||
t.Errorf("%v: expectedAssumeCall %v", name, item.expectAssumeCalled)
|
||||
}
|
||||
|
||||
if item.expectBindCalled != internalBinder.BindCalled {
|
||||
t.Errorf("%v: expectedBindCall %v", name, item.expectBindCalled)
|
||||
}
|
||||
|
||||
close(stop)
|
||||
}
|
||||
}
|
||||
105
vendor/k8s.io/kubernetes/pkg/scheduler/testutil.go
generated
vendored
Normal file
105
vendor/k8s.io/kubernetes/pkg/scheduler/testutil.go
generated
vendored
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
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 scheduler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
corelisters "k8s.io/client-go/listers/core/v1"
|
||||
"k8s.io/kubernetes/pkg/scheduler/algorithm"
|
||||
schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
|
||||
"k8s.io/kubernetes/pkg/scheduler/core"
|
||||
"k8s.io/kubernetes/pkg/scheduler/util"
|
||||
)
|
||||
|
||||
// FakeConfigurator is an implementation for test.
|
||||
type FakeConfigurator struct {
|
||||
Config *Config
|
||||
}
|
||||
|
||||
// GetPriorityFunctionConfigs is not implemented yet.
|
||||
func (fc *FakeConfigurator) GetPriorityFunctionConfigs(priorityKeys sets.String) ([]algorithm.PriorityConfig, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// GetPriorityMetadataProducer is not implemented yet.
|
||||
func (fc *FakeConfigurator) GetPriorityMetadataProducer() (algorithm.PriorityMetadataProducer, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// GetPredicateMetadataProducer is not implemented yet.
|
||||
func (fc *FakeConfigurator) GetPredicateMetadataProducer() (algorithm.PredicateMetadataProducer, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// GetPredicates is not implemented yet.
|
||||
func (fc *FakeConfigurator) GetPredicates(predicateKeys sets.String) (map[string]algorithm.FitPredicate, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
// GetHardPodAffinitySymmetricWeight is not implemented yet.
|
||||
func (fc *FakeConfigurator) GetHardPodAffinitySymmetricWeight() int32 {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// GetSchedulerName is not implemented yet.
|
||||
func (fc *FakeConfigurator) GetSchedulerName() string {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// MakeDefaultErrorFunc is not implemented yet.
|
||||
func (fc *FakeConfigurator) MakeDefaultErrorFunc(backoff *util.PodBackoff, podQueue core.SchedulingQueue) func(pod *v1.Pod, err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetNodeLister is not implemented yet.
|
||||
func (fc *FakeConfigurator) GetNodeLister() corelisters.NodeLister {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetClient is not implemented yet.
|
||||
func (fc *FakeConfigurator) GetClient() clientset.Interface {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetScheduledPodLister is not implemented yet.
|
||||
func (fc *FakeConfigurator) GetScheduledPodLister() corelisters.PodLister {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Create returns FakeConfigurator.Config
|
||||
func (fc *FakeConfigurator) Create() (*Config, error) {
|
||||
return fc.Config, nil
|
||||
}
|
||||
|
||||
// CreateFromProvider returns FakeConfigurator.Config
|
||||
func (fc *FakeConfigurator) CreateFromProvider(providerName string) (*Config, error) {
|
||||
return fc.Config, nil
|
||||
}
|
||||
|
||||
// CreateFromConfig returns FakeConfigurator.Config
|
||||
func (fc *FakeConfigurator) CreateFromConfig(policy schedulerapi.Policy) (*Config, error) {
|
||||
return fc.Config, nil
|
||||
}
|
||||
|
||||
// CreateFromKeys returns FakeConfigurator.Config
|
||||
func (fc *FakeConfigurator) CreateFromKeys(predicateKeys, priorityKeys sets.String, extenders []algorithm.SchedulerExtender) (*Config, error) {
|
||||
return fc.Config, nil
|
||||
}
|
||||
1
vendor/k8s.io/kubernetes/pkg/security/apparmor/BUILD
generated
vendored
1
vendor/k8s.io/kubernetes/pkg/security/apparmor/BUILD
generated
vendored
|
|
@ -61,7 +61,6 @@ go_test(
|
|||
"testdata/profiles",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
importpath = "k8s.io/kubernetes/pkg/security/apparmor",
|
||||
deps = [
|
||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
|
|
|
|||
22
vendor/k8s.io/kubernetes/pkg/serviceaccount/BUILD
generated
vendored
22
vendor/k8s.io/kubernetes/pkg/serviceaccount/BUILD
generated
vendored
|
|
@ -9,15 +9,19 @@ load(
|
|||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"claims.go",
|
||||
"jwt.go",
|
||||
"legacy.go",
|
||||
"util.go",
|
||||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/serviceaccount",
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//vendor/github.com/dgrijalva/jwt-go:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/gopkg.in/square/go-jose.v2:go_default_library",
|
||||
"//vendor/gopkg.in/square/go-jose.v2/jwt:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
|
|
@ -27,7 +31,6 @@ go_library(
|
|||
go_test(
|
||||
name = "go_default_xtest",
|
||||
srcs = ["jwt_test.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/serviceaccount_test",
|
||||
deps = [
|
||||
":go_default_library",
|
||||
"//pkg/controller/serviceaccount:go_default_library",
|
||||
|
|
@ -52,3 +55,18 @@ filegroup(
|
|||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = [
|
||||
"claims_test.go",
|
||||
"util_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//vendor/gopkg.in/square/go-jose.v2/jwt:go_default_library",
|
||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue