Unverified Commit 13845df0 authored by Erik Wilson's avatar Erik Wilson Committed by GitHub

Merge pull request #637 from erikwilson/update-v1.14.4-k3s.1

Update kubernetes to v1.14.4-k3s.1
parents f6701bbe 1d4442eb
...@@ -312,7 +312,7 @@ import: ...@@ -312,7 +312,7 @@ import:
- package: k8s.io/klog - package: k8s.io/klog
version: v0.2.0-14-g8e90cee79f8237 version: v0.2.0-14-g8e90cee79f8237
- package: k8s.io/kubernetes - package: k8s.io/kubernetes
version: v1.14.3-k3s.2 version: v1.14.4-k3s.1
repo: https://github.com/rancher/k3s.git repo: https://github.com/rancher/k3s.git
transitive: true transitive: true
staging: true staging: true
......
...@@ -9,7 +9,7 @@ package=github.com/opencontainers/runc/libcontainer/nsenter ...@@ -9,7 +9,7 @@ package=github.com/opencontainers/runc/libcontainer/nsenter
package=github.com/opencontainers/runc/libcontainer/specconv package=github.com/opencontainers/runc/libcontainer/specconv
package=github.com/opencontainers/runc/contrib/cmd/recvtty package=github.com/opencontainers/runc/contrib/cmd/recvtty
k8s.io/kubernetes v1.14.3-k3s.2 https://github.com/rancher/k3s.git transitive=true,staging=true k8s.io/kubernetes v1.14.4-k3s.1 https://github.com/rancher/k3s.git transitive=true,staging=true
github.com/rancher/wrangler 7737c167e16514a38229bc64c839cee8cd14e6d3 github.com/rancher/wrangler 7737c167e16514a38229bc64c839cee8cd14e6d3
github.com/rancher/wrangler-api v0.1.4 github.com/rancher/wrangler-api v0.1.4
......
...@@ -17,5 +17,5 @@ limitations under the License. ...@@ -17,5 +17,5 @@ limitations under the License.
// Package healthz implements basic http server health checking. // Package healthz implements basic http server health checking.
// Usage: // Usage:
// import "k8s.io/apiserver/pkg/server/healthz" // import "k8s.io/apiserver/pkg/server/healthz"
// healthz.DefaultHealthz() // healthz.InstallHandler(mux)
package healthz // import "k8s.io/apiserver/pkg/server/healthz" package healthz // import "k8s.io/apiserver/pkg/server/healthz"
...@@ -37,15 +37,6 @@ type HealthzChecker interface { ...@@ -37,15 +37,6 @@ type HealthzChecker interface {
Check(req *http.Request) error Check(req *http.Request) error
} }
var defaultHealthz = sync.Once{}
// DefaultHealthz installs the default healthz check to the http.DefaultServeMux.
func DefaultHealthz(checks ...HealthzChecker) {
defaultHealthz.Do(func() {
InstallHandler(http.DefaultServeMux, checks...)
})
}
// PingHealthz returns true automatically when checked // PingHealthz returns true automatically when checked
var PingHealthz HealthzChecker = ping{} var PingHealthz HealthzChecker = ping{}
......
...@@ -3,8 +3,8 @@ package version ...@@ -3,8 +3,8 @@ package version
var ( var (
gitMajor = "1" gitMajor = "1"
gitMinor = "14" gitMinor = "14"
gitVersion = "v1.14.3-k3s.2" gitVersion = "v1.14.4-k3s.1"
gitCommit = "6174f1fed28fd19300038f6578bf48e3920fa7ba" gitCommit = "ac992f3ef6c6d71e14366a1f65318e10eb3f4232"
gitTreeState = "clean" gitTreeState = "clean"
buildDate = "2019-06-21T08:17+00:00Z" buildDate = "2019-07-14T07:04+00:00Z"
) )
...@@ -159,6 +159,7 @@ func startAttachDetachController(ctx ControllerContext) (http.Handler, bool, err ...@@ -159,6 +159,7 @@ func startAttachDetachController(ctx ControllerContext) (http.Handler, bool, err
ctx.InformerFactory.Core().V1().PersistentVolumeClaims(), ctx.InformerFactory.Core().V1().PersistentVolumeClaims(),
ctx.InformerFactory.Core().V1().PersistentVolumes(), ctx.InformerFactory.Core().V1().PersistentVolumes(),
ctx.InformerFactory.Storage().V1beta1().CSINodes(), ctx.InformerFactory.Storage().V1beta1().CSINodes(),
ctx.InformerFactory.Storage().V1beta1().CSIDrivers(),
ProbeAttachableVolumePlugins(), ProbeAttachableVolumePlugins(),
GetDynamicPluginProber(ctx.ComponentConfig.PersistentVolumeBinderController.VolumeConfiguration), GetDynamicPluginProber(ctx.ComponentConfig.PersistentVolumeBinderController.VolumeConfiguration),
ctx.ComponentConfig.AttachDetachController.DisableAttachDetachReconcilerSync, ctx.ComponentConfig.AttachDetachController.DisableAttachDetachReconcilerSync,
......
...@@ -674,9 +674,10 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.Dependencies, stopCh <-chan ...@@ -674,9 +674,10 @@ func run(s *options.KubeletServer, kubeDeps *kubelet.Dependencies, stopCh <-chan
} }
if s.HealthzPort > 0 { if s.HealthzPort > 0 {
healthz.DefaultHealthz() mux := http.NewServeMux()
healthz.InstallHandler(mux)
go wait.Until(func() { go wait.Until(func() {
err := http.ListenAndServe(net.JoinHostPort(s.HealthzBindAddress, strconv.Itoa(int(s.HealthzPort))), nil) err := http.ListenAndServe(net.JoinHostPort(s.HealthzBindAddress, strconv.Itoa(int(s.HealthzPort))), mux)
if err != nil { if err != nil {
klog.Errorf("Starting health server failed: %v", err) klog.Errorf("Starting health server failed: %v", err)
} }
......
...@@ -406,12 +406,22 @@ func dropDisabledProcMountField(podSpec, oldPodSpec *api.PodSpec) { ...@@ -406,12 +406,22 @@ func dropDisabledProcMountField(podSpec, oldPodSpec *api.PodSpec) {
defaultProcMount := api.DefaultProcMount defaultProcMount := api.DefaultProcMount
for i := range podSpec.Containers { for i := range podSpec.Containers {
if podSpec.Containers[i].SecurityContext != nil { if podSpec.Containers[i].SecurityContext != nil {
podSpec.Containers[i].SecurityContext.ProcMount = &defaultProcMount if podSpec.Containers[i].SecurityContext.ProcMount != nil {
// The ProcMount field was improperly forced to non-nil in 1.12.
// If the feature is disabled, and the existing object is not using any non-default values, and the ProcMount field is present in the incoming object, force to the default value.
// Note: we cannot force the field to nil when the feature is disabled because it causes a diff against previously persisted data.
podSpec.Containers[i].SecurityContext.ProcMount = &defaultProcMount
}
} }
} }
for i := range podSpec.InitContainers { for i := range podSpec.InitContainers {
if podSpec.InitContainers[i].SecurityContext != nil { if podSpec.InitContainers[i].SecurityContext != nil {
podSpec.InitContainers[i].SecurityContext.ProcMount = &defaultProcMount if podSpec.InitContainers[i].SecurityContext.ProcMount != nil {
// The ProcMount field was improperly forced to non-nil in 1.12.
// If the feature is disabled, and the existing object is not using any non-default values, and the ProcMount field is present in the incoming object, force to the default value.
// Note: we cannot force the field to nil when the feature is disabled because it causes a diff against previously persisted data.
podSpec.InitContainers[i].SecurityContext.ProcMount = &defaultProcMount
}
} }
} }
} }
...@@ -473,7 +483,7 @@ func runtimeClassInUse(podSpec *api.PodSpec) bool { ...@@ -473,7 +483,7 @@ func runtimeClassInUse(podSpec *api.PodSpec) bool {
return false return false
} }
// procMountInUse returns true if the pod spec is non-nil and has a SecurityContext's ProcMount field set // procMountInUse returns true if the pod spec is non-nil and has a SecurityContext's ProcMount field set to a non-default value
func procMountInUse(podSpec *api.PodSpec) bool { func procMountInUse(podSpec *api.PodSpec) bool {
if podSpec == nil { if podSpec == nil {
return false return false
......
...@@ -136,9 +136,6 @@ func SetObjectDefaults_DaemonSet(in *v1.DaemonSet) { ...@@ -136,9 +136,6 @@ func SetObjectDefaults_DaemonSet(in *v1.DaemonSet) {
} }
} }
} }
if a.SecurityContext != nil {
corev1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -181,9 +178,6 @@ func SetObjectDefaults_DaemonSet(in *v1.DaemonSet) { ...@@ -181,9 +178,6 @@ func SetObjectDefaults_DaemonSet(in *v1.DaemonSet) {
} }
} }
} }
if a.SecurityContext != nil {
corev1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -289,9 +283,6 @@ func SetObjectDefaults_Deployment(in *v1.Deployment) { ...@@ -289,9 +283,6 @@ func SetObjectDefaults_Deployment(in *v1.Deployment) {
} }
} }
} }
if a.SecurityContext != nil {
corev1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -334,9 +325,6 @@ func SetObjectDefaults_Deployment(in *v1.Deployment) { ...@@ -334,9 +325,6 @@ func SetObjectDefaults_Deployment(in *v1.Deployment) {
} }
} }
} }
if a.SecurityContext != nil {
corev1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -442,9 +430,6 @@ func SetObjectDefaults_ReplicaSet(in *v1.ReplicaSet) { ...@@ -442,9 +430,6 @@ func SetObjectDefaults_ReplicaSet(in *v1.ReplicaSet) {
} }
} }
} }
if a.SecurityContext != nil {
corev1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -487,9 +472,6 @@ func SetObjectDefaults_ReplicaSet(in *v1.ReplicaSet) { ...@@ -487,9 +472,6 @@ func SetObjectDefaults_ReplicaSet(in *v1.ReplicaSet) {
} }
} }
} }
if a.SecurityContext != nil {
corev1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -595,9 +577,6 @@ func SetObjectDefaults_StatefulSet(in *v1.StatefulSet) { ...@@ -595,9 +577,6 @@ func SetObjectDefaults_StatefulSet(in *v1.StatefulSet) {
} }
} }
} }
if a.SecurityContext != nil {
corev1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -640,9 +619,6 @@ func SetObjectDefaults_StatefulSet(in *v1.StatefulSet) { ...@@ -640,9 +619,6 @@ func SetObjectDefaults_StatefulSet(in *v1.StatefulSet) {
} }
} }
} }
if a.SecurityContext != nil {
corev1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.VolumeClaimTemplates { for i := range in.Spec.VolumeClaimTemplates {
a := &in.Spec.VolumeClaimTemplates[i] a := &in.Spec.VolumeClaimTemplates[i]
......
...@@ -132,9 +132,6 @@ func SetObjectDefaults_Deployment(in *v1beta1.Deployment) { ...@@ -132,9 +132,6 @@ func SetObjectDefaults_Deployment(in *v1beta1.Deployment) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -177,9 +174,6 @@ func SetObjectDefaults_Deployment(in *v1beta1.Deployment) { ...@@ -177,9 +174,6 @@ func SetObjectDefaults_Deployment(in *v1beta1.Deployment) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -285,9 +279,6 @@ func SetObjectDefaults_StatefulSet(in *v1beta1.StatefulSet) { ...@@ -285,9 +279,6 @@ func SetObjectDefaults_StatefulSet(in *v1beta1.StatefulSet) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -330,9 +321,6 @@ func SetObjectDefaults_StatefulSet(in *v1beta1.StatefulSet) { ...@@ -330,9 +321,6 @@ func SetObjectDefaults_StatefulSet(in *v1beta1.StatefulSet) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.VolumeClaimTemplates { for i := range in.Spec.VolumeClaimTemplates {
a := &in.Spec.VolumeClaimTemplates[i] a := &in.Spec.VolumeClaimTemplates[i]
......
...@@ -136,9 +136,6 @@ func SetObjectDefaults_DaemonSet(in *v1beta2.DaemonSet) { ...@@ -136,9 +136,6 @@ func SetObjectDefaults_DaemonSet(in *v1beta2.DaemonSet) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -181,9 +178,6 @@ func SetObjectDefaults_DaemonSet(in *v1beta2.DaemonSet) { ...@@ -181,9 +178,6 @@ func SetObjectDefaults_DaemonSet(in *v1beta2.DaemonSet) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -289,9 +283,6 @@ func SetObjectDefaults_Deployment(in *v1beta2.Deployment) { ...@@ -289,9 +283,6 @@ func SetObjectDefaults_Deployment(in *v1beta2.Deployment) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -334,9 +325,6 @@ func SetObjectDefaults_Deployment(in *v1beta2.Deployment) { ...@@ -334,9 +325,6 @@ func SetObjectDefaults_Deployment(in *v1beta2.Deployment) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -442,9 +430,6 @@ func SetObjectDefaults_ReplicaSet(in *v1beta2.ReplicaSet) { ...@@ -442,9 +430,6 @@ func SetObjectDefaults_ReplicaSet(in *v1beta2.ReplicaSet) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -487,9 +472,6 @@ func SetObjectDefaults_ReplicaSet(in *v1beta2.ReplicaSet) { ...@@ -487,9 +472,6 @@ func SetObjectDefaults_ReplicaSet(in *v1beta2.ReplicaSet) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -595,9 +577,6 @@ func SetObjectDefaults_StatefulSet(in *v1beta2.StatefulSet) { ...@@ -595,9 +577,6 @@ func SetObjectDefaults_StatefulSet(in *v1beta2.StatefulSet) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -640,9 +619,6 @@ func SetObjectDefaults_StatefulSet(in *v1beta2.StatefulSet) { ...@@ -640,9 +619,6 @@ func SetObjectDefaults_StatefulSet(in *v1beta2.StatefulSet) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.VolumeClaimTemplates { for i := range in.Spec.VolumeClaimTemplates {
a := &in.Spec.VolumeClaimTemplates[i] a := &in.Spec.VolumeClaimTemplates[i]
......
...@@ -130,9 +130,6 @@ func SetObjectDefaults_Job(in *v1.Job) { ...@@ -130,9 +130,6 @@ func SetObjectDefaults_Job(in *v1.Job) {
} }
} }
} }
if a.SecurityContext != nil {
corev1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -175,9 +172,6 @@ func SetObjectDefaults_Job(in *v1.Job) { ...@@ -175,9 +172,6 @@ func SetObjectDefaults_Job(in *v1.Job) {
} }
} }
} }
if a.SecurityContext != nil {
corev1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
......
...@@ -131,9 +131,6 @@ func SetObjectDefaults_CronJob(in *v1beta1.CronJob) { ...@@ -131,9 +131,6 @@ func SetObjectDefaults_CronJob(in *v1beta1.CronJob) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.JobTemplate.Spec.Template.Spec.Containers { for i := range in.Spec.JobTemplate.Spec.Template.Spec.Containers {
a := &in.Spec.JobTemplate.Spec.Template.Spec.Containers[i] a := &in.Spec.JobTemplate.Spec.Template.Spec.Containers[i]
...@@ -176,9 +173,6 @@ func SetObjectDefaults_CronJob(in *v1beta1.CronJob) { ...@@ -176,9 +173,6 @@ func SetObjectDefaults_CronJob(in *v1beta1.CronJob) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -283,9 +277,6 @@ func SetObjectDefaults_JobTemplate(in *v1beta1.JobTemplate) { ...@@ -283,9 +277,6 @@ func SetObjectDefaults_JobTemplate(in *v1beta1.JobTemplate) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Template.Spec.Template.Spec.Containers { for i := range in.Template.Spec.Template.Spec.Containers {
a := &in.Template.Spec.Template.Spec.Containers[i] a := &in.Template.Spec.Template.Spec.Containers[i]
...@@ -328,8 +319,5 @@ func SetObjectDefaults_JobTemplate(in *v1beta1.JobTemplate) { ...@@ -328,8 +319,5 @@ func SetObjectDefaults_JobTemplate(in *v1beta1.JobTemplate) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -131,9 +131,6 @@ func SetObjectDefaults_CronJob(in *v2alpha1.CronJob) { ...@@ -131,9 +131,6 @@ func SetObjectDefaults_CronJob(in *v2alpha1.CronJob) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.JobTemplate.Spec.Template.Spec.Containers { for i := range in.Spec.JobTemplate.Spec.Template.Spec.Containers {
a := &in.Spec.JobTemplate.Spec.Template.Spec.Containers[i] a := &in.Spec.JobTemplate.Spec.Template.Spec.Containers[i]
...@@ -176,9 +173,6 @@ func SetObjectDefaults_CronJob(in *v2alpha1.CronJob) { ...@@ -176,9 +173,6 @@ func SetObjectDefaults_CronJob(in *v2alpha1.CronJob) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -283,9 +277,6 @@ func SetObjectDefaults_JobTemplate(in *v2alpha1.JobTemplate) { ...@@ -283,9 +277,6 @@ func SetObjectDefaults_JobTemplate(in *v2alpha1.JobTemplate) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Template.Spec.Template.Spec.Containers { for i := range in.Template.Spec.Template.Spec.Containers {
a := &in.Template.Spec.Template.Spec.Containers[i] a := &in.Template.Spec.Template.Spec.Containers[i]
...@@ -328,8 +319,5 @@ func SetObjectDefaults_JobTemplate(in *v2alpha1.JobTemplate) { ...@@ -328,8 +319,5 @@ func SetObjectDefaults_JobTemplate(in *v2alpha1.JobTemplate) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -421,10 +421,3 @@ func SetDefaults_HostPathVolumeSource(obj *v1.HostPathVolumeSource) { ...@@ -421,10 +421,3 @@ func SetDefaults_HostPathVolumeSource(obj *v1.HostPathVolumeSource) {
obj.Type = &typeVol obj.Type = &typeVol
} }
} }
func SetDefaults_SecurityContext(obj *v1.SecurityContext) {
if obj.ProcMount == nil {
defProcMount := v1.DefaultProcMount
obj.ProcMount = &defProcMount
}
}
...@@ -263,9 +263,6 @@ func SetObjectDefaults_Pod(in *v1.Pod) { ...@@ -263,9 +263,6 @@ func SetObjectDefaults_Pod(in *v1.Pod) {
} }
} }
} }
if a.SecurityContext != nil {
SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Containers { for i := range in.Spec.Containers {
a := &in.Spec.Containers[i] a := &in.Spec.Containers[i]
...@@ -308,9 +305,6 @@ func SetObjectDefaults_Pod(in *v1.Pod) { ...@@ -308,9 +305,6 @@ func SetObjectDefaults_Pod(in *v1.Pod) {
} }
} }
} }
if a.SecurityContext != nil {
SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -415,9 +409,6 @@ func SetObjectDefaults_PodTemplate(in *v1.PodTemplate) { ...@@ -415,9 +409,6 @@ func SetObjectDefaults_PodTemplate(in *v1.PodTemplate) {
} }
} }
} }
if a.SecurityContext != nil {
SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Template.Spec.Containers { for i := range in.Template.Spec.Containers {
a := &in.Template.Spec.Containers[i] a := &in.Template.Spec.Containers[i]
...@@ -460,9 +451,6 @@ func SetObjectDefaults_PodTemplate(in *v1.PodTemplate) { ...@@ -460,9 +451,6 @@ func SetObjectDefaults_PodTemplate(in *v1.PodTemplate) {
} }
} }
} }
if a.SecurityContext != nil {
SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -569,9 +557,6 @@ func SetObjectDefaults_ReplicationController(in *v1.ReplicationController) { ...@@ -569,9 +557,6 @@ func SetObjectDefaults_ReplicationController(in *v1.ReplicationController) {
} }
} }
} }
if a.SecurityContext != nil {
SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -614,9 +599,6 @@ func SetObjectDefaults_ReplicationController(in *v1.ReplicationController) { ...@@ -614,9 +599,6 @@ func SetObjectDefaults_ReplicationController(in *v1.ReplicationController) {
} }
} }
} }
if a.SecurityContext != nil {
SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
} }
......
...@@ -138,9 +138,6 @@ func SetObjectDefaults_DaemonSet(in *v1beta1.DaemonSet) { ...@@ -138,9 +138,6 @@ func SetObjectDefaults_DaemonSet(in *v1beta1.DaemonSet) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -183,9 +180,6 @@ func SetObjectDefaults_DaemonSet(in *v1beta1.DaemonSet) { ...@@ -183,9 +180,6 @@ func SetObjectDefaults_DaemonSet(in *v1beta1.DaemonSet) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -291,9 +285,6 @@ func SetObjectDefaults_Deployment(in *v1beta1.Deployment) { ...@@ -291,9 +285,6 @@ func SetObjectDefaults_Deployment(in *v1beta1.Deployment) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -336,9 +327,6 @@ func SetObjectDefaults_Deployment(in *v1beta1.Deployment) { ...@@ -336,9 +327,6 @@ func SetObjectDefaults_Deployment(in *v1beta1.Deployment) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
...@@ -466,9 +454,6 @@ func SetObjectDefaults_ReplicaSet(in *v1beta1.ReplicaSet) { ...@@ -466,9 +454,6 @@ func SetObjectDefaults_ReplicaSet(in *v1beta1.ReplicaSet) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
for i := range in.Spec.Template.Spec.Containers { for i := range in.Spec.Template.Spec.Containers {
a := &in.Spec.Template.Spec.Containers[i] a := &in.Spec.Template.Spec.Containers[i]
...@@ -511,9 +496,6 @@ func SetObjectDefaults_ReplicaSet(in *v1beta1.ReplicaSet) { ...@@ -511,9 +496,6 @@ func SetObjectDefaults_ReplicaSet(in *v1beta1.ReplicaSet) {
} }
} }
} }
if a.SecurityContext != nil {
v1.SetDefaults_SecurityContext(a.SecurityContext)
}
} }
} }
......
...@@ -23,7 +23,7 @@ import ( ...@@ -23,7 +23,7 @@ import (
autoscalingv1 "k8s.io/api/autoscaling/v1" autoscalingv1 "k8s.io/api/autoscaling/v1"
autoscalingv2 "k8s.io/api/autoscaling/v2beta2" autoscalingv2 "k8s.io/api/autoscaling/v2beta2"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality" apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
apimeta "k8s.io/apimachinery/pkg/api/meta" apimeta "k8s.io/apimachinery/pkg/api/meta"
...@@ -235,7 +235,8 @@ func (a *HorizontalController) processNextWorkItem() bool { ...@@ -235,7 +235,8 @@ func (a *HorizontalController) processNextWorkItem() bool {
func (a *HorizontalController) computeReplicasForMetrics(hpa *autoscalingv2.HorizontalPodAutoscaler, scale *autoscalingv1.Scale, func (a *HorizontalController) computeReplicasForMetrics(hpa *autoscalingv2.HorizontalPodAutoscaler, scale *autoscalingv1.Scale,
metricSpecs []autoscalingv2.MetricSpec) (replicas int32, metric string, statuses []autoscalingv2.MetricStatus, timestamp time.Time, err error) { metricSpecs []autoscalingv2.MetricSpec) (replicas int32, metric string, statuses []autoscalingv2.MetricStatus, timestamp time.Time, err error) {
currentReplicas := scale.Status.Replicas specReplicas := scale.Spec.Replicas
statusReplicas := scale.Status.Replicas
statuses = make([]autoscalingv2.MetricStatus, len(metricSpecs)) statuses = make([]autoscalingv2.MetricStatus, len(metricSpecs))
...@@ -267,7 +268,7 @@ func (a *HorizontalController) computeReplicasForMetrics(hpa *autoscalingv2.Hori ...@@ -267,7 +268,7 @@ func (a *HorizontalController) computeReplicasForMetrics(hpa *autoscalingv2.Hori
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetObjectMetric", "the HPA was unable to compute the replica count: %v", err) setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetObjectMetric", "the HPA was unable to compute the replica count: %v", err)
return 0, "", nil, time.Time{}, fmt.Errorf("failed to get object metric value: %v", err) return 0, "", nil, time.Time{}, fmt.Errorf("failed to get object metric value: %v", err)
} }
replicaCountProposal, timestampProposal, metricNameProposal, err = a.computeStatusForObjectMetric(currentReplicas, metricSpec, hpa, selector, &statuses[i], metricSelector) replicaCountProposal, timestampProposal, metricNameProposal, err = a.computeStatusForObjectMetric(specReplicas, statusReplicas, metricSpec, hpa, selector, &statuses[i], metricSelector)
if err != nil { if err != nil {
return 0, "", nil, time.Time{}, fmt.Errorf("failed to get object metric value: %v", err) return 0, "", nil, time.Time{}, fmt.Errorf("failed to get object metric value: %v", err)
} }
...@@ -278,17 +279,17 @@ func (a *HorizontalController) computeReplicasForMetrics(hpa *autoscalingv2.Hori ...@@ -278,17 +279,17 @@ func (a *HorizontalController) computeReplicasForMetrics(hpa *autoscalingv2.Hori
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetPodsMetric", "the HPA was unable to compute the replica count: %v", err) setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetPodsMetric", "the HPA was unable to compute the replica count: %v", err)
return 0, "", nil, time.Time{}, fmt.Errorf("failed to get pods metric value: %v", err) return 0, "", nil, time.Time{}, fmt.Errorf("failed to get pods metric value: %v", err)
} }
replicaCountProposal, timestampProposal, metricNameProposal, err = a.computeStatusForPodsMetric(currentReplicas, metricSpec, hpa, selector, &statuses[i], metricSelector) replicaCountProposal, timestampProposal, metricNameProposal, err = a.computeStatusForPodsMetric(specReplicas, metricSpec, hpa, selector, &statuses[i], metricSelector)
if err != nil { if err != nil {
return 0, "", nil, time.Time{}, fmt.Errorf("failed to get object metric value: %v", err) return 0, "", nil, time.Time{}, fmt.Errorf("failed to get object metric value: %v", err)
} }
case autoscalingv2.ResourceMetricSourceType: case autoscalingv2.ResourceMetricSourceType:
replicaCountProposal, timestampProposal, metricNameProposal, err = a.computeStatusForResourceMetric(currentReplicas, metricSpec, hpa, selector, &statuses[i]) replicaCountProposal, timestampProposal, metricNameProposal, err = a.computeStatusForResourceMetric(specReplicas, metricSpec, hpa, selector, &statuses[i])
if err != nil { if err != nil {
return 0, "", nil, time.Time{}, err return 0, "", nil, time.Time{}, err
} }
case autoscalingv2.ExternalMetricSourceType: case autoscalingv2.ExternalMetricSourceType:
replicaCountProposal, timestampProposal, metricNameProposal, err = a.computeStatusForExternalMetric(currentReplicas, metricSpec, hpa, selector, &statuses[i]) replicaCountProposal, timestampProposal, metricNameProposal, err = a.computeStatusForExternalMetric(specReplicas, statusReplicas, metricSpec, hpa, selector, &statuses[i])
if err != nil { if err != nil {
return 0, "", nil, time.Time{}, err return 0, "", nil, time.Time{}, err
} }
...@@ -326,9 +327,9 @@ func (a *HorizontalController) reconcileKey(key string) (deleted bool, err error ...@@ -326,9 +327,9 @@ func (a *HorizontalController) reconcileKey(key string) (deleted bool, err error
} }
// computeStatusForObjectMetric computes the desired number of replicas for the specified metric of type ObjectMetricSourceType. // computeStatusForObjectMetric computes the desired number of replicas for the specified metric of type ObjectMetricSourceType.
func (a *HorizontalController) computeStatusForObjectMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus, metricSelector labels.Selector) (int32, time.Time, string, error) { func (a *HorizontalController) computeStatusForObjectMetric(specReplicas, statusReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus, metricSelector labels.Selector) (int32, time.Time, string, error) {
if metricSpec.Object.Target.Type == autoscalingv2.ValueMetricType { if metricSpec.Object.Target.Type == autoscalingv2.ValueMetricType {
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetObjectMetricReplicas(currentReplicas, metricSpec.Object.Target.Value.MilliValue(), metricSpec.Object.Metric.Name, hpa.Namespace, &metricSpec.Object.DescribedObject, selector, metricSelector) replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetObjectMetricReplicas(specReplicas, metricSpec.Object.Target.Value.MilliValue(), metricSpec.Object.Metric.Name, hpa.Namespace, &metricSpec.Object.DescribedObject, selector, metricSelector)
if err != nil { if err != nil {
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetObjectMetric", err.Error()) a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetObjectMetric", err.Error())
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetObjectMetric", "the HPA was unable to compute the replica count: %v", err) setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetObjectMetric", "the HPA was unable to compute the replica count: %v", err)
...@@ -349,7 +350,7 @@ func (a *HorizontalController) computeStatusForObjectMetric(currentReplicas int3 ...@@ -349,7 +350,7 @@ func (a *HorizontalController) computeStatusForObjectMetric(currentReplicas int3
} }
return replicaCountProposal, timestampProposal, fmt.Sprintf("%s metric %s", metricSpec.Object.DescribedObject.Kind, metricSpec.Object.Metric.Name), nil return replicaCountProposal, timestampProposal, fmt.Sprintf("%s metric %s", metricSpec.Object.DescribedObject.Kind, metricSpec.Object.Metric.Name), nil
} else if metricSpec.Object.Target.Type == autoscalingv2.AverageValueMetricType { } else if metricSpec.Object.Target.Type == autoscalingv2.AverageValueMetricType {
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetObjectPerPodMetricReplicas(currentReplicas, metricSpec.Object.Target.AverageValue.MilliValue(), metricSpec.Object.Metric.Name, hpa.Namespace, &metricSpec.Object.DescribedObject, metricSelector) replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetObjectPerPodMetricReplicas(statusReplicas, metricSpec.Object.Target.AverageValue.MilliValue(), metricSpec.Object.Metric.Name, hpa.Namespace, &metricSpec.Object.DescribedObject, metricSelector)
if err != nil { if err != nil {
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetObjectMetric", err.Error()) a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetObjectMetric", err.Error())
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetObjectMetric", "the HPA was unable to compute the replica count: %v", err) setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetObjectMetric", "the HPA was unable to compute the replica count: %v", err)
...@@ -452,9 +453,9 @@ func (a *HorizontalController) computeStatusForResourceMetric(currentReplicas in ...@@ -452,9 +453,9 @@ func (a *HorizontalController) computeStatusForResourceMetric(currentReplicas in
} }
// computeStatusForExternalMetric computes the desired number of replicas for the specified metric of type ExternalMetricSourceType. // computeStatusForExternalMetric computes the desired number of replicas for the specified metric of type ExternalMetricSourceType.
func (a *HorizontalController) computeStatusForExternalMetric(currentReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus) (int32, time.Time, string, error) { func (a *HorizontalController) computeStatusForExternalMetric(specReplicas, statusReplicas int32, metricSpec autoscalingv2.MetricSpec, hpa *autoscalingv2.HorizontalPodAutoscaler, selector labels.Selector, status *autoscalingv2.MetricStatus) (int32, time.Time, string, error) {
if metricSpec.External.Target.AverageValue != nil { if metricSpec.External.Target.AverageValue != nil {
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetExternalPerPodMetricReplicas(currentReplicas, metricSpec.External.Target.AverageValue.MilliValue(), metricSpec.External.Metric.Name, hpa.Namespace, metricSpec.External.Metric.Selector) replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetExternalPerPodMetricReplicas(statusReplicas, metricSpec.External.Target.AverageValue.MilliValue(), metricSpec.External.Metric.Name, hpa.Namespace, metricSpec.External.Metric.Selector)
if err != nil { if err != nil {
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetExternalMetric", err.Error()) a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetExternalMetric", err.Error())
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetExternalMetric", "the HPA was unable to compute the replica count: %v", err) setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetExternalMetric", "the HPA was unable to compute the replica count: %v", err)
...@@ -475,7 +476,7 @@ func (a *HorizontalController) computeStatusForExternalMetric(currentReplicas in ...@@ -475,7 +476,7 @@ func (a *HorizontalController) computeStatusForExternalMetric(currentReplicas in
return replicaCountProposal, timestampProposal, fmt.Sprintf("external metric %s(%+v)", metricSpec.External.Metric.Name, metricSpec.External.Metric.Selector), nil return replicaCountProposal, timestampProposal, fmt.Sprintf("external metric %s(%+v)", metricSpec.External.Metric.Name, metricSpec.External.Metric.Selector), nil
} }
if metricSpec.External.Target.Value != nil { if metricSpec.External.Target.Value != nil {
replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetExternalMetricReplicas(currentReplicas, metricSpec.External.Target.Value.MilliValue(), metricSpec.External.Metric.Name, hpa.Namespace, metricSpec.External.Metric.Selector, selector) replicaCountProposal, utilizationProposal, timestampProposal, err := a.replicaCalc.GetExternalMetricReplicas(specReplicas, metricSpec.External.Target.Value.MilliValue(), metricSpec.External.Metric.Name, hpa.Namespace, metricSpec.External.Metric.Selector, selector)
if err != nil { if err != nil {
a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetExternalMetric", err.Error()) a.eventRecorder.Event(hpa, v1.EventTypeWarning, "FailedGetExternalMetric", err.Error())
setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetExternalMetric", "the HPA was unable to compute the replica count: %v", err) setCondition(hpa, autoscalingv2.ScalingActive, v1.ConditionFalse, "FailedGetExternalMetric", "the HPA was unable to compute the replica count: %v", err)
...@@ -550,7 +551,7 @@ func (a *HorizontalController) reconcileAutoscaler(hpav1Shared *autoscalingv1.Ho ...@@ -550,7 +551,7 @@ func (a *HorizontalController) reconcileAutoscaler(hpav1Shared *autoscalingv1.Ho
return fmt.Errorf("failed to query scale subresource for %s: %v", reference, err) return fmt.Errorf("failed to query scale subresource for %s: %v", reference, err)
} }
setCondition(hpa, autoscalingv2.AbleToScale, v1.ConditionTrue, "SucceededGetScale", "the HPA controller was able to get the target's current scale") setCondition(hpa, autoscalingv2.AbleToScale, v1.ConditionTrue, "SucceededGetScale", "the HPA controller was able to get the target's current scale")
currentReplicas := scale.Status.Replicas currentReplicas := scale.Spec.Replicas
a.recordInitialRecommendation(currentReplicas, key) a.recordInitialRecommendation(currentReplicas, key)
var metricStatuses []autoscalingv2.MetricStatus var metricStatuses []autoscalingv2.MetricStatus
......
...@@ -22,7 +22,7 @@ import ( ...@@ -22,7 +22,7 @@ import (
"time" "time"
autoscaling "k8s.io/api/autoscaling/v2beta2" autoscaling "k8s.io/api/autoscaling/v2beta2"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
...@@ -333,7 +333,7 @@ func (c *ReplicaCalculator) GetExternalMetricReplicas(currentReplicas int32, tar ...@@ -333,7 +333,7 @@ func (c *ReplicaCalculator) GetExternalMetricReplicas(currentReplicas int32, tar
// GetExternalPerPodMetricReplicas calculates the desired replica count based on a // GetExternalPerPodMetricReplicas calculates the desired replica count based on a
// target metric value per pod (as a milli-value) for the external metric in the // target metric value per pod (as a milli-value) for the external metric in the
// given namespace, and the current replica count. // given namespace, and the current replica count.
func (c *ReplicaCalculator) GetExternalPerPodMetricReplicas(currentReplicas int32, targetUtilizationPerPod int64, metricName, namespace string, metricSelector *metav1.LabelSelector) (replicaCount int32, utilization int64, timestamp time.Time, err error) { func (c *ReplicaCalculator) GetExternalPerPodMetricReplicas(statusReplicas int32, targetUtilizationPerPod int64, metricName, namespace string, metricSelector *metav1.LabelSelector) (replicaCount int32, utilization int64, timestamp time.Time, err error) {
metricLabelSelector, err := metav1.LabelSelectorAsSelector(metricSelector) metricLabelSelector, err := metav1.LabelSelectorAsSelector(metricSelector)
if err != nil { if err != nil {
return 0, 0, time.Time{}, err return 0, 0, time.Time{}, err
...@@ -347,13 +347,13 @@ func (c *ReplicaCalculator) GetExternalPerPodMetricReplicas(currentReplicas int3 ...@@ -347,13 +347,13 @@ func (c *ReplicaCalculator) GetExternalPerPodMetricReplicas(currentReplicas int3
utilization = utilization + val utilization = utilization + val
} }
replicaCount = currentReplicas replicaCount = statusReplicas
usageRatio := float64(utilization) / (float64(targetUtilizationPerPod) * float64(replicaCount)) usageRatio := float64(utilization) / (float64(targetUtilizationPerPod) * float64(replicaCount))
if math.Abs(1.0-usageRatio) > c.tolerance { if math.Abs(1.0-usageRatio) > c.tolerance {
// update number of replicas if the change is large enough // update number of replicas if the change is large enough
replicaCount = int32(math.Ceil(float64(utilization) / float64(targetUtilizationPerPod))) replicaCount = int32(math.Ceil(float64(utilization) / float64(targetUtilizationPerPod)))
} }
utilization = int64(math.Ceil(float64(utilization) / float64(currentReplicas))) utilization = int64(math.Ceil(float64(utilization) / float64(statusReplicas)))
return replicaCount, utilization, timestamp, nil return replicaCount, utilization, timestamp, nil
} }
......
...@@ -30,6 +30,7 @@ import ( ...@@ -30,6 +30,7 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/runtime" "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature"
coreinformers "k8s.io/client-go/informers/core/v1" coreinformers "k8s.io/client-go/informers/core/v1"
storageinformers "k8s.io/client-go/informers/storage/v1beta1" storageinformers "k8s.io/client-go/informers/storage/v1beta1"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
...@@ -48,6 +49,7 @@ import ( ...@@ -48,6 +49,7 @@ import (
"k8s.io/kubernetes/pkg/controller/volume/attachdetach/reconciler" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/reconciler"
"k8s.io/kubernetes/pkg/controller/volume/attachdetach/statusupdater" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/statusupdater"
"k8s.io/kubernetes/pkg/controller/volume/attachdetach/util" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/util"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
...@@ -103,6 +105,7 @@ func NewAttachDetachController( ...@@ -103,6 +105,7 @@ func NewAttachDetachController(
pvcInformer coreinformers.PersistentVolumeClaimInformer, pvcInformer coreinformers.PersistentVolumeClaimInformer,
pvInformer coreinformers.PersistentVolumeInformer, pvInformer coreinformers.PersistentVolumeInformer,
csiNodeInformer storageinformers.CSINodeInformer, csiNodeInformer storageinformers.CSINodeInformer,
csiDriverInformer storageinformers.CSIDriverInformer,
plugins []volume.VolumePlugin, plugins []volume.VolumePlugin,
prober volume.DynamicPluginProber, prober volume.DynamicPluginProber,
disableReconciliationSync bool, disableReconciliationSync bool,
...@@ -136,6 +139,11 @@ func NewAttachDetachController( ...@@ -136,6 +139,11 @@ func NewAttachDetachController(
pvcQueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "pvcs"), pvcQueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "pvcs"),
} }
if utilfeature.DefaultFeatureGate.Enabled(features.CSIDriverRegistry) {
adc.csiDriverLister = csiDriverInformer.Lister()
adc.csiDriversSynced = csiDriverInformer.Informer().HasSynced
}
if err := adc.volumePluginMgr.InitPlugins(plugins, prober, adc); err != nil { if err := adc.volumePluginMgr.InitPlugins(plugins, prober, adc); err != nil {
return nil, fmt.Errorf("Could not initialize volume plugins for Attach/Detach Controller: %+v", err) return nil, fmt.Errorf("Could not initialize volume plugins for Attach/Detach Controller: %+v", err)
} }
...@@ -260,6 +268,12 @@ type attachDetachController struct { ...@@ -260,6 +268,12 @@ type attachDetachController struct {
csiNodeLister storagelisters.CSINodeLister csiNodeLister storagelisters.CSINodeLister
csiNodeSynced kcache.InformerSynced csiNodeSynced kcache.InformerSynced
// csiDriverLister is the shared CSIDriver lister used to fetch and store
// CSIDriver objects from the API server. It is shared with other controllers
// and therefore the CSIDriver objects in its store should be treated as immutable.
csiDriverLister storagelisters.CSIDriverLister
csiDriversSynced kcache.InformerSynced
// volumePluginMgr used to initialize and fetch volume plugins // volumePluginMgr used to initialize and fetch volume plugins
volumePluginMgr volume.VolumePluginMgr volumePluginMgr volume.VolumePluginMgr
...@@ -313,6 +327,9 @@ func (adc *attachDetachController) Run(stopCh <-chan struct{}) { ...@@ -313,6 +327,9 @@ func (adc *attachDetachController) Run(stopCh <-chan struct{}) {
if adc.csiNodeSynced != nil { if adc.csiNodeSynced != nil {
synced = append(synced, adc.csiNodeSynced) synced = append(synced, adc.csiNodeSynced)
} }
if adc.csiDriversSynced != nil {
synced = append(synced, adc.csiDriversSynced)
}
if !controller.WaitForCacheSync("attach detach", stopCh, synced...) { if !controller.WaitForCacheSync("attach detach", stopCh, synced...) {
return return
...@@ -655,6 +672,10 @@ func (adc *attachDetachController) CSINodeLister() storagelisters.CSINodeLister ...@@ -655,6 +672,10 @@ func (adc *attachDetachController) CSINodeLister() storagelisters.CSINodeLister
return adc.csiNodeLister return adc.csiNodeLister
} }
func (adc *attachDetachController) CSIDriverLister() storagelisters.CSIDriverLister {
return adc.csiDriverLister
}
func (adc *attachDetachController) IsAttachDetachController() bool { func (adc *attachDetachController) IsAttachDetachController() bool {
return true return true
} }
...@@ -775,3 +796,7 @@ func (adc *attachDetachController) GetSubpather() subpath.Interface { ...@@ -775,3 +796,7 @@ func (adc *attachDetachController) GetSubpather() subpath.Interface {
// Subpaths not needed in attachdetach controller // Subpaths not needed in attachdetach controller
return nil return nil
} }
func (adc *attachDetachController) GetCSIDriverLister() storagelisters.CSIDriverLister {
return adc.csiDriverLister
}
...@@ -132,9 +132,11 @@ go_library( ...@@ -132,9 +132,11 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
"//staging/src/k8s.io/client-go/listers/core/v1:go_default_library", "//staging/src/k8s.io/client-go/listers/core/v1:go_default_library",
"//staging/src/k8s.io/client-go/listers/storage/v1beta1:go_default_library",
"//staging/src/k8s.io/client-go/tools/cache:go_default_library", "//staging/src/k8s.io/client-go/tools/cache:go_default_library",
"//staging/src/k8s.io/client-go/tools/record:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library",
"//staging/src/k8s.io/client-go/util/certificate:go_default_library", "//staging/src/k8s.io/client-go/util/certificate:go_default_library",
......
...@@ -239,7 +239,7 @@ func getSupportedSubsystems() map[subsystem]bool { ...@@ -239,7 +239,7 @@ func getSupportedSubsystems() map[subsystem]bool {
supportedSubsystems := map[subsystem]bool{ supportedSubsystems := map[subsystem]bool{
&cgroupfs.MemoryGroup{}: true, &cgroupfs.MemoryGroup{}: true,
&cgroupfs.CpuGroup{}: true, &cgroupfs.CpuGroup{}: true,
&cgroupfs.PidsGroup{}: true, &cgroupfs.PidsGroup{}: false,
} }
// not all hosts support hugetlb cgroup, and in the absent of hugetlb, we will fail silently by reporting no capacity. // not all hosts support hugetlb cgroup, and in the absent of hugetlb, we will fail silently by reporting no capacity.
supportedSubsystems[&cgroupfs.HugetlbGroup{}] = false supportedSubsystems[&cgroupfs.HugetlbGroup{}] = false
......
...@@ -477,11 +477,15 @@ func (m *kubeGenericRuntimeManager) computePodActions(pod *v1.Pod, podStatus *ku ...@@ -477,11 +477,15 @@ func (m *kubeGenericRuntimeManager) computePodActions(pod *v1.Pod, podStatus *ku
// If we need to (re-)create the pod sandbox, everything will need to be // If we need to (re-)create the pod sandbox, everything will need to be
// killed and recreated, and init containers should be purged. // killed and recreated, and init containers should be purged.
if createPodSandbox { if createPodSandbox {
if !shouldRestartOnFailure(pod) && attempt != 0 { if !shouldRestartOnFailure(pod) && attempt != 0 && len(podStatus.ContainerStatuses) != 0 {
// Should not restart the pod, just return. // Should not restart the pod, just return.
// we should not create a sandbox for a pod if it is already done. // we should not create a sandbox for a pod if it is already done.
// if all containers are done and should not be started, there is no need to create a new sandbox. // if all containers are done and should not be started, there is no need to create a new sandbox.
// this stops confusing logs on pods whose containers all have exit codes, but we recreate a sandbox before terminating it. // this stops confusing logs on pods whose containers all have exit codes, but we recreate a sandbox before terminating it.
//
// If ContainerStatuses is empty, we assume that we've never
// successfully created any containers. In this case, we should
// retry creating the sandbox.
changes.CreateSandbox = false changes.CreateSandbox = false
return changes return changes
} }
......
...@@ -19,6 +19,7 @@ limitations under the License. ...@@ -19,6 +19,7 @@ limitations under the License.
package stats package stats
import ( import (
"fmt"
"time" "time"
"github.com/Microsoft/hcsshim" "github.com/Microsoft/hcsshim"
...@@ -40,18 +41,11 @@ func (p *criStatsProvider) listContainerNetworkStats() (map[string]*statsapi.Net ...@@ -40,18 +41,11 @@ func (p *criStatsProvider) listContainerNetworkStats() (map[string]*statsapi.Net
stats := make(map[string]*statsapi.NetworkStats) stats := make(map[string]*statsapi.NetworkStats)
for _, c := range containers { for _, c := range containers {
container, err := hcsshim.OpenContainer(c.ID) cstats, err := fetchContainerStats(c)
if err != nil { if err != nil {
klog.V(4).Infof("Failed to open container %q with error '%v', continue to get stats for other containers", c.ID, err) klog.V(4).Infof("Failed to fetch statistics for container %q with error '%v', continue to get stats for other containers", c.ID, err)
continue continue
} }
cstats, err := container.Statistics()
if err != nil {
klog.V(4).Infof("Failed to get statistics for container %q with error '%v', continue to get stats for other containers", c.ID, err)
continue
}
if len(cstats.Network) > 0 { if len(cstats.Network) > 0 {
stats[c.ID] = hcsStatsToNetworkStats(cstats.Timestamp, cstats.Network) stats[c.ID] = hcsStatsToNetworkStats(cstats.Timestamp, cstats.Network)
} }
...@@ -60,6 +54,27 @@ func (p *criStatsProvider) listContainerNetworkStats() (map[string]*statsapi.Net ...@@ -60,6 +54,27 @@ func (p *criStatsProvider) listContainerNetworkStats() (map[string]*statsapi.Net
return stats, nil return stats, nil
} }
func fetchContainerStats(c hcsshim.ContainerProperties) (stats hcsshim.Statistics, err error) {
var (
container hcsshim.Container
)
container, err = hcsshim.OpenContainer(c.ID)
if err != nil {
return
}
defer func() {
if closeErr := container.Close(); closeErr != nil {
if err != nil {
err = fmt.Errorf("failed to close container after error %v; close error: %v", err, closeErr)
} else {
err = closeErr
}
}
}()
return container.Statistics()
}
// hcsStatsToNetworkStats converts hcsshim.Statistics.Network to statsapi.NetworkStats // hcsStatsToNetworkStats converts hcsshim.Statistics.Network to statsapi.NetworkStats
func hcsStatsToNetworkStats(timestamp time.Time, hcsStats []hcsshim.NetworkStats) *statsapi.NetworkStats { func hcsStatsToNetworkStats(timestamp time.Time, hcsStats []hcsshim.NetworkStats) *statsapi.NetworkStats {
result := &statsapi.NetworkStats{ result := &statsapi.NetworkStats{
......
...@@ -26,8 +26,14 @@ import ( ...@@ -26,8 +26,14 @@ import (
authenticationv1 "k8s.io/api/authentication/v1" authenticationv1 "k8s.io/api/authentication/v1"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/informers"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
storagelisters "k8s.io/client-go/listers/storage/v1beta1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/kubelet/configmap" "k8s.io/kubernetes/pkg/kubelet/configmap"
"k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/secret" "k8s.io/kubernetes/pkg/kubelet/secret"
...@@ -52,12 +58,33 @@ func NewInitializedVolumePluginMgr( ...@@ -52,12 +58,33 @@ func NewInitializedVolumePluginMgr(
plugins []volume.VolumePlugin, plugins []volume.VolumePlugin,
prober volume.DynamicPluginProber) (*volume.VolumePluginMgr, error) { prober volume.DynamicPluginProber) (*volume.VolumePluginMgr, error) {
// Initialize csiDriverLister before calling InitPlugins
var informerFactory informers.SharedInformerFactory
var csiDriverLister storagelisters.CSIDriverLister
var csiDriversSynced cache.InformerSynced
const resyncPeriod = 0
if utilfeature.DefaultFeatureGate.Enabled(features.CSIDriverRegistry) {
// Don't initialize if kubeClient is nil
if kubelet.kubeClient != nil {
informerFactory = informers.NewSharedInformerFactory(kubelet.kubeClient, resyncPeriod)
csiDriverInformer := informerFactory.Storage().V1beta1().CSIDrivers()
csiDriverLister = csiDriverInformer.Lister()
csiDriversSynced = csiDriverInformer.Informer().HasSynced
} else {
klog.Warning("kubeClient is nil. Skip initialization of CSIDriverLister")
}
}
kvh := &kubeletVolumeHost{ kvh := &kubeletVolumeHost{
kubelet: kubelet, kubelet: kubelet,
volumePluginMgr: volume.VolumePluginMgr{}, volumePluginMgr: volume.VolumePluginMgr{},
secretManager: secretManager, secretManager: secretManager,
configMapManager: configMapManager, configMapManager: configMapManager,
tokenManager: tokenManager, tokenManager: tokenManager,
informerFactory: informerFactory,
csiDriverLister: csiDriverLister,
csiDriversSynced: csiDriversSynced,
} }
if err := kvh.volumePluginMgr.InitPlugins(plugins, prober, kvh); err != nil { if err := kvh.volumePluginMgr.InitPlugins(plugins, prober, kvh); err != nil {
...@@ -83,6 +110,9 @@ type kubeletVolumeHost struct { ...@@ -83,6 +110,9 @@ type kubeletVolumeHost struct {
secretManager secret.Manager secretManager secret.Manager
tokenManager *token.Manager tokenManager *token.Manager
configMapManager configmap.Manager configMapManager configmap.Manager
informerFactory informers.SharedInformerFactory
csiDriverLister storagelisters.CSIDriverLister
csiDriversSynced cache.InformerSynced
} }
func (kvh *kubeletVolumeHost) SetKubeletError(err error) { func (kvh *kubeletVolumeHost) SetKubeletError(err error) {
...@@ -121,6 +151,34 @@ func (kvh *kubeletVolumeHost) GetSubpather() subpath.Interface { ...@@ -121,6 +151,34 @@ func (kvh *kubeletVolumeHost) GetSubpather() subpath.Interface {
return kvh.kubelet.subpather return kvh.kubelet.subpather
} }
func (kvh *kubeletVolumeHost) GetInformerFactory() informers.SharedInformerFactory {
return kvh.informerFactory
}
func (kvh *kubeletVolumeHost) CSIDriverLister() storagelisters.CSIDriverLister {
return kvh.csiDriverLister
}
func (kvh *kubeletVolumeHost) CSIDriversSynced() cache.InformerSynced {
return kvh.csiDriversSynced
}
// WaitForCacheSync is a helper function that waits for cache sync for CSIDriverLister
func (kvh *kubeletVolumeHost) WaitForCacheSync() error {
if kvh.csiDriversSynced == nil {
klog.Error("csiDriversSynced not found on KubeletVolumeHost")
return fmt.Errorf("csiDriversSynced not found on KubeletVolumeHost")
}
synced := []cache.InformerSynced{kvh.csiDriversSynced}
if !cache.WaitForCacheSync(wait.NeverStop, synced...) {
klog.Warning("failed to wait for cache sync for CSIDriverLister")
return fmt.Errorf("failed to wait for cache sync for CSIDriverLister")
}
return nil
}
func (kvh *kubeletVolumeHost) NewWrapperMounter( func (kvh *kubeletVolumeHost) NewWrapperMounter(
volName string, volName string,
spec volume.Spec, spec volume.Spec,
......
...@@ -250,6 +250,11 @@ func (vm *volumeManager) Run(sourcesReady config.SourcesReady, stopCh <-chan str ...@@ -250,6 +250,11 @@ func (vm *volumeManager) Run(sourcesReady config.SourcesReady, stopCh <-chan str
metrics.Register(vm.actualStateOfWorld, vm.desiredStateOfWorld, vm.volumePluginMgr) metrics.Register(vm.actualStateOfWorld, vm.desiredStateOfWorld, vm.volumePluginMgr)
if vm.kubeClient != nil {
// start informer for CSIDriver
vm.volumePluginMgr.Run(stopCh)
}
<-stopCh <-stopCh
klog.Infof("Shutting down Kubelet Volume Manager") klog.Infof("Shutting down Kubelet Volume Manager")
} }
......
...@@ -17,6 +17,7 @@ go_library( ...@@ -17,6 +17,7 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/proxy", importpath = "k8s.io/kubernetes/pkg/proxy",
deps = [ deps = [
"//pkg/api/v1/service:go_default_library", "//pkg/api/v1/service:go_default_library",
"//pkg/proxy/metrics:go_default_library",
"//pkg/proxy/util:go_default_library", "//pkg/proxy/util:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
......
...@@ -29,6 +29,7 @@ import ( ...@@ -29,6 +29,7 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/kubernetes/pkg/proxy/metrics"
utilproxy "k8s.io/kubernetes/pkg/proxy/util" utilproxy "k8s.io/kubernetes/pkg/proxy/util"
utilnet "k8s.io/utils/net" utilnet "k8s.io/utils/net"
) )
...@@ -127,6 +128,7 @@ func (ect *EndpointChangeTracker) Update(previous, current *v1.Endpoints) bool { ...@@ -127,6 +128,7 @@ func (ect *EndpointChangeTracker) Update(previous, current *v1.Endpoints) bool {
if endpoints == nil { if endpoints == nil {
return false return false
} }
metrics.EndpointChangesTotal.Inc()
namespacedName := types.NamespacedName{Namespace: endpoints.Namespace, Name: endpoints.Name} namespacedName := types.NamespacedName{Namespace: endpoints.Namespace, Name: endpoints.Name}
ect.lock.Lock() ect.lock.Lock()
...@@ -154,6 +156,8 @@ func (ect *EndpointChangeTracker) Update(previous, current *v1.Endpoints) bool { ...@@ -154,6 +156,8 @@ func (ect *EndpointChangeTracker) Update(previous, current *v1.Endpoints) bool {
// should be exported. // should be exported.
delete(ect.lastChangeTriggerTimes, namespacedName) delete(ect.lastChangeTriggerTimes, namespacedName)
} }
metrics.EndpointChangesPending.Set(float64(len(ect.items)))
return len(ect.items) > 0 return len(ect.items) > 0
} }
...@@ -295,6 +299,7 @@ func (endpointsMap EndpointsMap) apply(changes *EndpointChangeTracker, staleEndp ...@@ -295,6 +299,7 @@ func (endpointsMap EndpointsMap) apply(changes *EndpointChangeTracker, staleEndp
detectStaleConnections(change.previous, change.current, staleEndpoints, staleServiceNames) detectStaleConnections(change.previous, change.current, staleEndpoints, staleServiceNames)
} }
changes.items = make(map[types.NamespacedName]*endpointsChange) changes.items = make(map[types.NamespacedName]*endpointsChange)
metrics.EndpointChangesPending.Set(0)
for _, lastChangeTriggerTime := range changes.lastChangeTriggerTimes { for _, lastChangeTriggerTime := range changes.lastChangeTriggerTimes {
*lastChangeTriggerTimes = append(*lastChangeTriggerTimes, lastChangeTriggerTime...) *lastChangeTriggerTimes = append(*lastChangeTriggerTimes, lastChangeTriggerTime...)
} }
......
...@@ -1387,6 +1387,7 @@ func (proxier *Proxier) syncProxyRules() { ...@@ -1387,6 +1387,7 @@ func (proxier *Proxier) syncProxyRules() {
if proxier.healthzServer != nil { if proxier.healthzServer != nil {
proxier.healthzServer.UpdateTimestamp() proxier.healthzServer.UpdateTimestamp()
} }
metrics.SyncProxyRulesLastTimestamp.SetToCurrentTime()
// Update healthchecks. The endpoints list might include services that are // Update healthchecks. The endpoints list might include services that are
// not "OnlyLocal", but the services list will not, and the healthChecker // not "OnlyLocal", but the services list will not, and the healthChecker
......
...@@ -18,6 +18,7 @@ package ipvs ...@@ -18,6 +18,7 @@ package ipvs
import ( import (
"fmt" "fmt"
"strings"
"sync" "sync"
"time" "time"
...@@ -167,7 +168,7 @@ func (m *GracefulTerminationManager) deleteRsFunc(rsToDelete *listItem) (bool, e ...@@ -167,7 +168,7 @@ func (m *GracefulTerminationManager) deleteRsFunc(rsToDelete *listItem) (bool, e
// For UDP traffic, no graceful termination, we immediately delete the RS // For UDP traffic, no graceful termination, we immediately delete the RS
// (existing connections will be deleted on the next packet because sysctlExpireNoDestConn=1) // (existing connections will be deleted on the next packet because sysctlExpireNoDestConn=1)
// For other protocols, don't delete until all connections have expired) // For other protocols, don't delete until all connections have expired)
if rsToDelete.VirtualServer.Protocol != "udp" && rs.ActiveConn+rs.InactiveConn != 0 { if strings.ToUpper(rsToDelete.VirtualServer.Protocol) != "UDP" && rs.ActiveConn+rs.InactiveConn != 0 {
klog.Infof("Not deleting, RS %v: %v ActiveConn, %v InactiveConn", rsToDelete.String(), rs.ActiveConn, rs.InactiveConn) klog.Infof("Not deleting, RS %v: %v ActiveConn, %v InactiveConn", rsToDelete.String(), rs.ActiveConn, rs.InactiveConn)
return false, nil return false, nil
} }
......
...@@ -1245,6 +1245,7 @@ func (proxier *Proxier) syncProxyRules() { ...@@ -1245,6 +1245,7 @@ func (proxier *Proxier) syncProxyRules() {
if proxier.healthzServer != nil { if proxier.healthzServer != nil {
proxier.healthzServer.UpdateTimestamp() proxier.healthzServer.UpdateTimestamp()
} }
metrics.SyncProxyRulesLastTimestamp.SetToCurrentTime()
// Update healthchecks. The endpoints list might include services that are // Update healthchecks. The endpoints list might include services that are
// not "OnlyLocal", but the services list will not, and the healthChecker // not "OnlyLocal", but the services list will not, and the healthChecker
......
...@@ -46,6 +46,16 @@ var ( ...@@ -46,6 +46,16 @@ var (
}, },
) )
// SyncProxyRulesLastTimestamp is the timestamp proxy rules were last
// successfully synced.
SyncProxyRulesLastTimestamp = prometheus.NewGauge(
prometheus.GaugeOpts{
Subsystem: kubeProxySubsystem,
Name: "sync_proxy_rules_last_timestamp_seconds",
Help: "The last time proxy rules were successfully synced",
},
)
// NetworkProgrammingLatency is defined as the time it took to program the network - from the time // NetworkProgrammingLatency is defined as the time it took to program the network - from the time
// the service or pod has changed to the time the change was propagated and the proper kube-proxy // the service or pod has changed to the time the change was propagated and the proper kube-proxy
// rules were synced. Exported for each endpoints object that were part of the rules sync. // rules were synced. Exported for each endpoints object that were part of the rules sync.
...@@ -63,6 +73,46 @@ var ( ...@@ -63,6 +73,46 @@ var (
Buckets: prometheus.ExponentialBuckets(0.001, 2, 20), Buckets: prometheus.ExponentialBuckets(0.001, 2, 20),
}, },
) )
// EndpointChangesPending is the number of pending endpoint changes that
// have not yet been synced to the proxy.
EndpointChangesPending = prometheus.NewGauge(
prometheus.GaugeOpts{
Subsystem: kubeProxySubsystem,
Name: "sync_proxy_rules_endpoint_changes_pending",
Help: "Pending proxy rules Endpoint changes",
},
)
// EndpointChangesTotal is the number of endpoint changes that the proxy
// has seen.
EndpointChangesTotal = prometheus.NewCounter(
prometheus.CounterOpts{
Subsystem: kubeProxySubsystem,
Name: "sync_proxy_rules_endpoint_changes_total",
Help: "Cumulative proxy rules Endpoint changes",
},
)
// ServiceChangesPending is the number of pending service changes that
// have not yet been synced to the proxy.
ServiceChangesPending = prometheus.NewGauge(
prometheus.GaugeOpts{
Subsystem: kubeProxySubsystem,
Name: "sync_proxy_rules_service_changes_pending",
Help: "Pending proxy rules Service changes",
},
)
// ServiceChangesTotal is the number of service changes that the proxy has
// seen.
ServiceChangesTotal = prometheus.NewCounter(
prometheus.CounterOpts{
Subsystem: kubeProxySubsystem,
Name: "sync_proxy_rules_service_changes_total",
Help: "Cumulative proxy rules Service changes",
},
)
) )
var registerMetricsOnce sync.Once var registerMetricsOnce sync.Once
...@@ -72,7 +122,12 @@ func RegisterMetrics() { ...@@ -72,7 +122,12 @@ func RegisterMetrics() {
registerMetricsOnce.Do(func() { registerMetricsOnce.Do(func() {
prometheus.MustRegister(SyncProxyRulesLatency) prometheus.MustRegister(SyncProxyRulesLatency)
prometheus.MustRegister(DeprecatedSyncProxyRulesLatency) prometheus.MustRegister(DeprecatedSyncProxyRulesLatency)
prometheus.MustRegister(SyncProxyRulesLastTimestamp)
prometheus.MustRegister(NetworkProgrammingLatency) prometheus.MustRegister(NetworkProgrammingLatency)
prometheus.MustRegister(EndpointChangesPending)
prometheus.MustRegister(EndpointChangesTotal)
prometheus.MustRegister(ServiceChangesPending)
prometheus.MustRegister(ServiceChangesTotal)
}) })
} }
......
...@@ -30,6 +30,7 @@ import ( ...@@ -30,6 +30,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
apiservice "k8s.io/kubernetes/pkg/api/v1/service" apiservice "k8s.io/kubernetes/pkg/api/v1/service"
"k8s.io/kubernetes/pkg/proxy/metrics"
utilproxy "k8s.io/kubernetes/pkg/proxy/util" utilproxy "k8s.io/kubernetes/pkg/proxy/util"
utilnet "k8s.io/utils/net" utilnet "k8s.io/utils/net"
) )
...@@ -198,6 +199,7 @@ func (sct *ServiceChangeTracker) Update(previous, current *v1.Service) bool { ...@@ -198,6 +199,7 @@ func (sct *ServiceChangeTracker) Update(previous, current *v1.Service) bool {
if svc == nil { if svc == nil {
return false return false
} }
metrics.ServiceChangesTotal.Inc()
namespacedName := types.NamespacedName{Namespace: svc.Namespace, Name: svc.Name} namespacedName := types.NamespacedName{Namespace: svc.Namespace, Name: svc.Name}
sct.lock.Lock() sct.lock.Lock()
...@@ -214,6 +216,7 @@ func (sct *ServiceChangeTracker) Update(previous, current *v1.Service) bool { ...@@ -214,6 +216,7 @@ func (sct *ServiceChangeTracker) Update(previous, current *v1.Service) bool {
if reflect.DeepEqual(change.previous, change.current) { if reflect.DeepEqual(change.previous, change.current) {
delete(sct.items, namespacedName) delete(sct.items, namespacedName)
} }
metrics.ServiceChangesPending.Set(float64(len(sct.items)))
return len(sct.items) > 0 return len(sct.items) > 0
} }
...@@ -296,6 +299,7 @@ func (serviceMap *ServiceMap) apply(changes *ServiceChangeTracker, UDPStaleClust ...@@ -296,6 +299,7 @@ func (serviceMap *ServiceMap) apply(changes *ServiceChangeTracker, UDPStaleClust
} }
// clear changes after applying them to ServiceMap. // clear changes after applying them to ServiceMap.
changes.items = make(map[types.NamespacedName]*serviceChange) changes.items = make(map[types.NamespacedName]*serviceChange)
metrics.ServiceChangesPending.Set(0)
return return
} }
......
...@@ -43,6 +43,16 @@ var ( ...@@ -43,6 +43,16 @@ var (
Buckets: prometheus.ExponentialBuckets(1000, 2, 15), Buckets: prometheus.ExponentialBuckets(1000, 2, 15),
}, },
) )
// SyncProxyRulesLastTimestamp is the timestamp proxy rules were last
// successfully synced.
SyncProxyRulesLastTimestamp = prometheus.NewGauge(
prometheus.GaugeOpts{
Subsystem: kubeProxySubsystem,
Name: "sync_proxy_rules_last_timestamp_seconds",
Help: "The last time proxy rules were successfully synced",
},
)
) )
var registerMetricsOnce sync.Once var registerMetricsOnce sync.Once
...@@ -51,6 +61,7 @@ func RegisterMetrics() { ...@@ -51,6 +61,7 @@ func RegisterMetrics() {
registerMetricsOnce.Do(func() { registerMetricsOnce.Do(func() {
prometheus.MustRegister(SyncProxyRulesLatency) prometheus.MustRegister(SyncProxyRulesLatency)
prometheus.MustRegister(DeprecatedSyncProxyRulesLatency) prometheus.MustRegister(DeprecatedSyncProxyRulesLatency)
prometheus.MustRegister(SyncProxyRulesLastTimestamp)
}) })
} }
......
...@@ -1197,6 +1197,7 @@ func (proxier *Proxier) syncProxyRules() { ...@@ -1197,6 +1197,7 @@ func (proxier *Proxier) syncProxyRules() {
if proxier.healthzServer != nil { if proxier.healthzServer != nil {
proxier.healthzServer.UpdateTimestamp() proxier.healthzServer.UpdateTimestamp()
} }
SyncProxyRulesLastTimestamp.SetToCurrentTime()
// Update healthchecks. The endpoints list might include services that are // Update healthchecks. The endpoints list might include services that are
// not "OnlyLocal", but the services list will not, and the healthChecker // not "OnlyLocal", but the services list will not, and the healthChecker
......
...@@ -234,7 +234,7 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) { ...@@ -234,7 +234,7 @@ func (mounter *Mounter) IsLikelyNotMountPoint(file string) (bool, error) {
if err != nil { if err != nil {
return true, err return true, err
} }
rootStat, err := os.Lstat(filepath.Dir(strings.TrimSuffix(file, "/"))) rootStat, err := os.Stat(filepath.Dir(strings.TrimSuffix(file, "/")))
if err != nil { if err != nil {
return true, err return true, err
} }
......
...@@ -3,8 +3,8 @@ package version ...@@ -3,8 +3,8 @@ package version
var ( var (
gitMajor = "1" gitMajor = "1"
gitMinor = "14" gitMinor = "14"
gitVersion = "v1.14.3-k3s.2" gitVersion = "v1.14.4-k3s.1"
gitCommit = "6174f1fed28fd19300038f6578bf48e3920fa7ba" gitCommit = "ac992f3ef6c6d71e14366a1f65318e10eb3f4232"
gitTreeState = "clean" gitTreeState = "clean"
buildDate = "2019-06-21T08:17+00:00Z" buildDate = "2019-07-14T07:04+00:00Z"
) )
...@@ -18,6 +18,7 @@ go_library( ...@@ -18,6 +18,7 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/volume", importpath = "k8s.io/kubernetes/pkg/volume",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//pkg/features:go_default_library",
"//pkg/util/mount:go_default_library", "//pkg/util/mount:go_default_library",
"//pkg/volume/util/fs:go_default_library", "//pkg/volume/util/fs:go_default_library",
"//pkg/volume/util/recyclerclient:go_default_library", "//pkg/volume/util/recyclerclient:go_default_library",
...@@ -29,8 +30,11 @@ go_library( ...@@ -29,8 +30,11 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/listers/storage/v1beta1:go_default_library", "//staging/src/k8s.io/client-go/listers/storage/v1beta1:go_default_library",
"//staging/src/k8s.io/client-go/tools/cache:go_default_library",
"//staging/src/k8s.io/client-go/tools/record:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library",
"//staging/src/k8s.io/cloud-provider:go_default_library", "//staging/src/k8s.io/cloud-provider:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
......
...@@ -31,8 +31,6 @@ go_library( ...@@ -31,8 +31,6 @@ go_library(
"//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/informers/storage/v1beta1:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/listers/storage/v1beta1:go_default_library", "//staging/src/k8s.io/client-go/listers/storage/v1beta1:go_default_library",
"//staging/src/k8s.io/csi-translation-lib/plugins:go_default_library", "//staging/src/k8s.io/csi-translation-lib/plugins:go_default_library",
...@@ -73,6 +71,7 @@ go_test( ...@@ -73,6 +71,7 @@ go_test(
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature/testing:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes:go_default_library", "//staging/src/k8s.io/client-go/kubernetes:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library", "//staging/src/k8s.io/client-go/testing:go_default_library",
......
...@@ -19,7 +19,6 @@ package csi ...@@ -19,7 +19,6 @@ package csi
import ( import (
"context" "context"
"crypto/sha256" "crypto/sha256"
"errors"
"fmt" "fmt"
"os" "os"
"path" "path"
...@@ -276,8 +275,14 @@ func (c *csiMountMgr) podAttributes() (map[string]string, error) { ...@@ -276,8 +275,14 @@ func (c *csiMountMgr) podAttributes() (map[string]string, error) {
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIDriverRegistry) { if !utilfeature.DefaultFeatureGate.Enabled(features.CSIDriverRegistry) {
return nil, nil return nil, nil
} }
kletHost, ok := c.plugin.host.(volume.KubeletVolumeHost)
if ok {
kletHost.WaitForCacheSync()
}
if c.plugin.csiDriverLister == nil { if c.plugin.csiDriverLister == nil {
return nil, errors.New("CSIDriver lister does not exist") return nil, fmt.Errorf("CSIDriverLister not found")
} }
csiDriver, err := c.plugin.csiDriverLister.Get(string(c.driverName)) csiDriver, err := c.plugin.csiDriverLister.Get(string(c.driverName))
......
...@@ -35,12 +35,9 @@ import ( ...@@ -35,12 +35,9 @@ import (
meta "k8s.io/apimachinery/pkg/apis/meta/v1" meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
utilversion "k8s.io/apimachinery/pkg/util/version" utilversion "k8s.io/apimachinery/pkg/util/version"
"k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature" utilfeature "k8s.io/apiserver/pkg/util/feature"
csiapiinformer "k8s.io/client-go/informers"
csiinformer "k8s.io/client-go/informers/storage/v1beta1"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
csilister "k8s.io/client-go/listers/storage/v1beta1" storagelisters "k8s.io/client-go/listers/storage/v1beta1"
"k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume"
"k8s.io/kubernetes/pkg/volume/csi/nodeinfomanager" "k8s.io/kubernetes/pkg/volume/csi/nodeinfomanager"
...@@ -73,10 +70,9 @@ var ( ...@@ -73,10 +70,9 @@ var (
var deprecatedSocketDirVersions = []string{"0.1.0", "0.2.0", "0.3.0", "0.4.0"} var deprecatedSocketDirVersions = []string{"0.1.0", "0.2.0", "0.3.0", "0.4.0"}
type csiPlugin struct { type csiPlugin struct {
host volume.VolumeHost host volume.VolumeHost
blockEnabled bool blockEnabled bool
csiDriverLister csilister.CSIDriverLister csiDriverLister storagelisters.CSIDriverLister
csiDriverInformer csiinformer.CSIDriverInformer
} }
//TODO (vladimirvivien) add this type to storage api //TODO (vladimirvivien) add this type to storage api
...@@ -244,11 +240,21 @@ func (p *csiPlugin) Init(host volume.VolumeHost) error { ...@@ -244,11 +240,21 @@ func (p *csiPlugin) Init(host volume.VolumeHost) error {
if csiClient == nil { if csiClient == nil {
klog.Warning(log("kubeclient not set, assuming standalone kubelet")) klog.Warning(log("kubeclient not set, assuming standalone kubelet"))
} else { } else {
// Start informer for CSIDrivers. // set CSIDriverLister
factory := csiapiinformer.NewSharedInformerFactory(csiClient, csiResyncPeriod) adcHost, ok := host.(volume.AttachDetachVolumeHost)
p.csiDriverInformer = factory.Storage().V1beta1().CSIDrivers() if ok {
p.csiDriverLister = p.csiDriverInformer.Lister() p.csiDriverLister = adcHost.CSIDriverLister()
go factory.Start(wait.NeverStop) if p.csiDriverLister == nil {
klog.Error(log("CSIDriverLister not found on AttachDetachVolumeHost"))
}
}
kletHost, ok := host.(volume.KubeletVolumeHost)
if ok {
p.csiDriverLister = kletHost.CSIDriverLister()
if p.csiDriverLister == nil {
klog.Error(log("CSIDriverLister not found on KubeletVolumeHost"))
}
}
} }
} }
...@@ -682,6 +688,12 @@ func (p *csiPlugin) skipAttach(driver string) (bool, error) { ...@@ -682,6 +688,12 @@ func (p *csiPlugin) skipAttach(driver string) (bool, error) {
if !utilfeature.DefaultFeatureGate.Enabled(features.CSIDriverRegistry) { if !utilfeature.DefaultFeatureGate.Enabled(features.CSIDriverRegistry) {
return false, nil return false, nil
} }
kletHost, ok := p.host.(volume.KubeletVolumeHost)
if ok {
kletHost.WaitForCacheSync()
}
if p.csiDriverLister == nil { if p.csiDriverLister == nil {
return false, errors.New("CSIDriver lister does not exist") return false, errors.New("CSIDriver lister does not exist")
} }
......
...@@ -42,15 +42,15 @@ func (f *flexVolumeUnmounter) TearDown() error { ...@@ -42,15 +42,15 @@ func (f *flexVolumeUnmounter) TearDown() error {
} }
func (f *flexVolumeUnmounter) TearDownAt(dir string) error { func (f *flexVolumeUnmounter) TearDownAt(dir string) error {
pathExists, pathErr := mount.PathExists(dir) pathExists, pathErr := mount.PathExists(dir)
if !pathExists { if pathErr != nil {
klog.Warningf("Warning: Unmount skipped because path does not exist: %v", dir) // only log warning here since plugins should anyways have to deal with errors
return nil klog.Warningf("Error checking path: %v", pathErr)
} } else {
if !pathExists {
if pathErr != nil && !mount.IsCorruptedMnt(pathErr) { klog.Warningf("Warning: Unmount skipped because path does not exist: %v", dir)
return fmt.Errorf("Error checking path: %v", pathErr) return nil
}
} }
call := f.plugin.NewDriverCall(unmountCmd) call := f.plugin.NewDriverCall(unmountCmd)
......
...@@ -25,10 +25,14 @@ import ( ...@@ -25,10 +25,14 @@ import (
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
utilerrors "k8s.io/apimachinery/pkg/util/errors" utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/informers"
clientset "k8s.io/client-go/kubernetes" clientset "k8s.io/client-go/kubernetes"
storagelisters "k8s.io/client-go/listers/storage/v1beta1" storagelisters "k8s.io/client-go/listers/storage/v1beta1"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/klog" "k8s.io/klog"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/util/mount" "k8s.io/kubernetes/pkg/util/mount"
"k8s.io/kubernetes/pkg/volume/util/recyclerclient" "k8s.io/kubernetes/pkg/volume/util/recyclerclient"
"k8s.io/kubernetes/pkg/volume/util/subpath" "k8s.io/kubernetes/pkg/volume/util/subpath"
...@@ -317,6 +321,15 @@ type KubeletVolumeHost interface { ...@@ -317,6 +321,15 @@ type KubeletVolumeHost interface {
// SetKubeletError lets plugins set an error on the Kubelet runtime status // SetKubeletError lets plugins set an error on the Kubelet runtime status
// that will cause the Kubelet to post NotReady status with the error message provided // that will cause the Kubelet to post NotReady status with the error message provided
SetKubeletError(err error) SetKubeletError(err error)
// GetInformerFactory returns the informer factory for CSIDriverLister
GetInformerFactory() informers.SharedInformerFactory
// CSIDriverLister returns the informer lister for the CSIDriver API Object
CSIDriverLister() storagelisters.CSIDriverLister
// CSIDriverSynced returns the informer synced for the CSIDriver API Object
CSIDriversSynced() cache.InformerSynced
// WaitForCacheSync is a helper function that waits for cache sync for CSIDriverLister
WaitForCacheSync() error
} }
// AttachDetachVolumeHost is a AttachDetach Controller specific interface that plugins can use // AttachDetachVolumeHost is a AttachDetach Controller specific interface that plugins can use
...@@ -325,6 +338,9 @@ type AttachDetachVolumeHost interface { ...@@ -325,6 +338,9 @@ type AttachDetachVolumeHost interface {
// CSINodeLister returns the informer lister for the CSINode API Object // CSINodeLister returns the informer lister for the CSINode API Object
CSINodeLister() storagelisters.CSINodeLister CSINodeLister() storagelisters.CSINodeLister
// CSIDriverLister returns the informer lister for the CSIDriver API Object
CSIDriverLister() storagelisters.CSIDriverLister
// IsAttachDetachController is an interface marker to strictly tie AttachDetachVolumeHost // IsAttachDetachController is an interface marker to strictly tie AttachDetachVolumeHost
// to the attachDetachController // to the attachDetachController
IsAttachDetachController() bool IsAttachDetachController() bool
...@@ -1003,6 +1019,17 @@ func (pm *VolumePluginMgr) FindNodeExpandablePluginByName(name string) (NodeExpa ...@@ -1003,6 +1019,17 @@ func (pm *VolumePluginMgr) FindNodeExpandablePluginByName(name string) (NodeExpa
return nil, nil return nil, nil
} }
func (pm *VolumePluginMgr) Run(stopCh <-chan struct{}) {
kletHost, ok := pm.Host.(KubeletVolumeHost)
if ok {
// start informer for CSIDriver
if utilfeature.DefaultFeatureGate.Enabled(features.CSIDriverRegistry) {
informerFactory := kletHost.GetInformerFactory()
go informerFactory.Start(stopCh)
}
}
}
// NewPersistentVolumeRecyclerPodTemplate creates a template for a recycler // NewPersistentVolumeRecyclerPodTemplate creates a template for a recycler
// pod. By default, a recycler pod simply runs "rm -rf" on a volume and tests // pod. By default, a recycler pod simply runs "rm -rf" on a volume and tests
// for emptiness. Most attributes of the template will be correct for most // for emptiness. Most attributes of the template will be correct for most
......
...@@ -398,7 +398,7 @@ func doSafeMakeDir(pathname string, base string, perm os.FileMode) error { ...@@ -398,7 +398,7 @@ func doSafeMakeDir(pathname string, base string, perm os.FileMode) error {
return fmt.Errorf("cannot create directory %s: %s", currentPath, err) return fmt.Errorf("cannot create directory %s: %s", currentPath, err)
} }
// Dive into the created directory // Dive into the created directory
childFD, err := syscall.Openat(parentFD, dir, nofollowFlags, 0) childFD, err = syscall.Openat(parentFD, dir, nofollowFlags, 0)
if err != nil { if err != nil {
return fmt.Errorf("cannot open %s: %s", currentPath, err) return fmt.Errorf("cannot open %s: %s", currentPath, err)
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment