<commit_before>/*
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 core

import (
	"log"
	"time"

	"k8s.io/autoscaler/vertical-pod-autoscaler/apimock"
	recommender "k8s.io/autoscaler/vertical-pod-autoscaler/recommender_mock"

	"k8s.io/api/admissionregistration/v1alpha1"
	"k8s.io/api/core/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/fields"
	"k8s.io/apimachinery/pkg/labels"
	runtime "k8s.io/apimachinery/pkg/runtime"
	watch "k8s.io/apimachinery/pkg/watch"
	"k8s.io/client-go/tools/cache"
	"k8s.io/kubernetes/pkg/api"
	kubeclient "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
	admissionregistrationv1alpha1 "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/admissionregistration/v1alpha1"

	"github.com/golang/glog"
)

const (
	// VPAInitializerConfigName is a unique name of the VPA initializer config,
	// used to register the initializer with apiserver.
	VPAInitializerConfigName = "vpa-initializer-config.k8s.io"
	// VPAInitializerName is a unique name of VPA initializer, used to mark
	// pods that need to be initialized by VPA initializer.
	VPAInitializerName = "vpa-initializer.k8s.io"

	retries     = 5
	retryPeriod = 1000 * time.Millisecond
)

// Initializer initializes all uninitialized pods matched by an existing VPA object.
// Takes resource recommendations from recommender or recommendations cached
// in VPA object if recommender is unavailable and applies them to containers
// in the pod.
// On startup initializers registers itself with API Server by creating a VPA
// initializer configuration.
type Initializer interface {
	// Run runs the initializer by syncing caches and registering with the API server
	Run(stopCh <-chan struct{})
}

type initializer struct {
	client      kubeclient.Interface
	vpaLister   apimock.VerticalPodAutoscalerLister
	podSynced   cache.InformerSynced
	informer    cache.SharedInformer
	recommender recommender.CachingRecommender
	registerer  admissionregistrationv1alpha1.InitializerConfigurationInterface
}

// Run starts and syncs the initializer's caches and registers initializer with
// the API sever.
func (initializer *initializer) Run(stopCh <-chan struct{}) {
	glog.Infof("starting VPA initializer")
	defer glog.Infof("shutting down VPA initializer")

	err := initializer.register()
	if err != nil {
		log.Fatalf("failed to register VPA initializer: %v", err)
	}
	defer initializer.unregister()
	go initializer.informer.Run(stopCh)

	if !cache.WaitForCacheSync(stopCh, initializer.podSynced) {
		glog.Fatalf("Failed to sync caches for VPA initializer")
	}

	<-stopCh
}

func (initializer *initializer) register() error {
	configuration := newConfiguration()
	config, err := initializer.registerer.Create(configuration)
	if err != nil {
		if apierrors.IsAlreadyExists(err) {
			return nil
		}
		return err
	}
	glog.V(1).Infof("registered VPA initializer with config name %v", config.Name)
	return nil
}

func (initializer *initializer) unregister() {
	err := initializer.registerer.Delete(VPAInitializerConfigName, &metav1.DeleteOptions{})
	if err != nil {
		glog.Error("failed to unregister VPA initializer: %v", err)
	}
}

func (initializer *initializer) updateResourceRequests(obj interface{}) {
	pod, ok := obj.(*v1.Pod)
	if !ok {
		glog.Errorf("can't update resource requests, object is not v1.Pod")
		return
	}

	if !shouldInitialize(pod) {
		glog.V(3).Infof("not updating pod: %v, VPA initializer not in the beginning of pending initializers list", pod.Name)
		return
	}
	initializedPod, err := initializer.initializePod(pod)

	if err != nil {
		glog.Errorf("unable to initialize pod: %v", pod.Name)
		// Mark failed initialization for pod.
		failedPod, err := markAsFailed(pod)
		if err != nil {
			glog.Errorf("unable to mark failed initialization for pod %v: %v", pod.Name, err)
		}
		err = initializer.doUpdatePod(failedPod)
		if err != nil {
			glog.Errorf("unable to mark failed initialization for pod %v: %v", pod.Name, err)
		}
	}
	err = initializer.doUpdatePod(initializedPod)
	if err != nil {
		glog.Errorf("error updating pod %v: %v", initializedPod.Name, err)
	}
}

func (initializer *initializer) doUpdatePod(pod *v1.Pod) error {
	var err error
	for i := 0; i < retries; i++ {
		if _, err = initializer.client.CoreV1().Pods(pod.Namespace).Update(pod); err == nil {
			return nil<commit_msg>Fix error branch in pod initialization<commit_after>/*
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 core

import (
	"log"
	"time"

	"k8s.io/autoscaler/vertical-pod-autoscaler/apimock"
	recommender "k8s.io/autoscaler/vertical-pod-autoscaler/recommender_mock"

	"k8s.io/api/admissionregistration/v1alpha1"
	"k8s.io/api/core/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/fields"
	"k8s.io/apimachinery/pkg/labels"
	runtime "k8s.io/apimachinery/pkg/runtime"
	watch "k8s.io/apimachinery/pkg/watch"
	"k8s.io/client-go/tools/cache"
	"k8s.io/kubernetes/pkg/api"
	kubeclient "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
	admissionregistrationv1alpha1 "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/admissionregistration/v1alpha1"

	"github.com/golang/glog"
)

const (
	// VPAInitializerConfigName is a unique name of the VPA initializer config,
	// used to register the initializer with apiserver.
	VPAInitializerConfigName = "vpa-initializer-config.k8s.io"
	// VPAInitializerName is a unique name of VPA initializer, used to mark
	// pods that need to be initialized by VPA initializer.
	VPAInitializerName = "vpa-initializer.k8s.io"

	retries     = 5
	retryPeriod = 1000 * time.Millisecond
)

// Initializer initializes all uninitialized pods matched by an existing VPA object.
// Takes resource recommendations from recommender or recommendations cached
// in VPA object if recommender is unavailable and applies them to containers
// in the pod.
// On startup initializers registers itself with API Server by creating a VPA
// initializer configuration.
type Initializer interface {
	// Run runs the initializer by syncing caches and registering with the API server
	Run(stopCh <-chan struct{})
}

type initializer struct {
	client      kubeclient.Interface
	vpaLister   apimock.VerticalPodAutoscalerLister
	podSynced   cache.InformerSynced
	informer    cache.SharedInformer
	recommender recommender.CachingRecommender
	registerer  admissionregistrationv1alpha1.InitializerConfigurationInterface
}

// Run starts and syncs the initializer's caches and registers initializer with
// the API sever.
func (initializer *initializer) Run(stopCh <-chan struct{}) {
	glog.Infof("starting VPA initializer")
	defer glog.Infof("shutting down VPA initializer")

	err := initializer.register()
	if err != nil {
		log.Fatalf("failed to register VPA initializer: %v", err)
	}
	defer initializer.unregister()
	go initializer.informer.Run(stopCh)

	if !cache.WaitForCacheSync(stopCh, initializer.podSynced) {
		glog.Fatalf("Failed to sync caches for VPA initializer")
	}

	<-stopCh
}

func (initializer *initializer) register() error {
	configuration := newConfiguration()
	config, err := initializer.registerer.Create(configuration)
	if err != nil {
		if apierrors.IsAlreadyExists(err) {
			return nil
		}
		return err
	}
	glog.V(1).Infof("registered VPA initializer with config name %v", config.Name)
	return nil
}

func (initializer *initializer) unregister() {
	err := initializer.registerer.Delete(VPAInitializerConfigName, &metav1.DeleteOptions{})
	if err != nil {
		glog.Error("failed to unregister VPA initializer: %v", err)
	}
}

func (initializer *initializer) updateResourceRequests(obj interface{}) {
	pod, ok := obj.(*v1.Pod)
	if !ok {
		glog.Errorf("can't update resource requests, object is not v1.Pod")
		return
	}

	if !shouldInitialize(pod) {
		glog.V(3).Infof("not updating pod: %v, VPA initializer not in the beginning of pending initializers list", pod.Name)
		return
	}
	initializedPod, err := initializer.initializePod(pod)

	if err != nil {
		glog.Errorf("unable to initialize pod: %v", pod.Name)
		// Mark failed initialization for pod.
		failedPod, err := markAsFailed(pod)
		if err != nil {
			glog.Errorf("unable to mark failed initialization for pod %v: %v", pod.Name, err)
			return
		}
		err = initializer.doUpdatePod(failedPod)
		if err != nil {
			glog.Errorf("unable to update pod %v after failed initialization: %v", pod.Name, err)
		}
		return
	}
	err = initializer.doUpdatePod(initializedPod)
	if err != nil {
		glog.Errorf("error updating pod %v: %v", initializedPod.Name, err)
	}
}

func (initializer *initializer) doUpdatePod(pod *v1.Pod) error {
	var err error
	for i := 0; i < retries; i++ {
		if _, err = initializer.client.CoreV1().Pods(pod.Namespace).Update(pod); err == nil {
			return nil
{'fraction_non_alphanumeric': 0.10113498175922173, 'fraction_numerical': 0.009728415079043373, 'mean_word_length': 4.51648965902739, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6610734', 'n_tokens_mistral': 3351, 'n_tokens_neox': 3213, 'n_words': 930}