Improve logging
This commit is contained in:
		
							parent
							
								
									08b6dfb691
								
							
						
					
					
						commit
						1ad5992160
					
				|  | @ -9,6 +9,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/apis" | 	"github.com/jenkinsci/kubernetes-operator/pkg/apis" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins" | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins" | ||||||
|  | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/event" | 	"github.com/jenkinsci/kubernetes-operator/pkg/event" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/version" | 	"github.com/jenkinsci/kubernetes-operator/version" | ||||||
|  | @ -17,6 +18,7 @@ import ( | ||||||
| 	"github.com/operator-framework/operator-sdk/pkg/leader" | 	"github.com/operator-framework/operator-sdk/pkg/leader" | ||||||
| 	"github.com/operator-framework/operator-sdk/pkg/ready" | 	"github.com/operator-framework/operator-sdk/pkg/ready" | ||||||
| 	sdkVersion "github.com/operator-framework/operator-sdk/version" | 	sdkVersion "github.com/operator-framework/operator-sdk/version" | ||||||
|  | 	"github.com/pkg/errors" | ||||||
| 	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp" | 	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp" | ||||||
| 	"sigs.k8s.io/controller-runtime/pkg/client/config" | 	"sigs.k8s.io/controller-runtime/pkg/client/config" | ||||||
| 	"sigs.k8s.io/controller-runtime/pkg/manager" | 	"sigs.k8s.io/controller-runtime/pkg/manager" | ||||||
|  | @ -37,31 +39,31 @@ func main() { | ||||||
| 	debug := flag.Bool("debug", false, "Set log level to debug") | 	debug := flag.Bool("debug", false, "Set log level to debug") | ||||||
| 	flag.Parse() | 	flag.Parse() | ||||||
| 
 | 
 | ||||||
| 	log.SetupLogger(debug) | 	log.SetupLogger(*debug) | ||||||
| 	printInfo() | 	printInfo() | ||||||
| 
 | 
 | ||||||
| 	namespace, err := k8sutil.GetWatchNamespace() | 	namespace, err := k8sutil.GetWatchNamespace() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		fatal(err, "failed to get watch namespace") | 		fatal(errors.Wrap(err, "failed to get watch namespace"), *debug) | ||||||
| 	} | 	} | ||||||
| 	log.Log.Info(fmt.Sprintf("watch namespace: %v", namespace)) | 	log.Log.Info(fmt.Sprintf("watch namespace: %v", namespace)) | ||||||
| 
 | 
 | ||||||
| 	// get a config to talk to the apiserver
 | 	// get a config to talk to the apiserver
 | ||||||
| 	cfg, err := config.GetConfig() | 	cfg, err := config.GetConfig() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		fatal(err, "failed to get config") | 		fatal(errors.Wrap(err, "failed to get config"), *debug) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// become the leader before proceeding
 | 	// become the leader before proceeding
 | ||||||
| 	err = leader.Become(context.TODO(), "jenkins-operator-lock") | 	err = leader.Become(context.TODO(), "jenkins-operator-lock") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		fatal(err, "failed to become leader") | 		fatal(errors.Wrap(err, "failed to become leader"), *debug) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	r := ready.NewFileReady() | 	r := ready.NewFileReady() | ||||||
| 	err = r.Set() | 	err = r.Set() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		fatal(err, "failed to get ready.NewFileReady") | 		fatal(errors.Wrap(err, "failed to get ready.NewFileReady"), *debug) | ||||||
| 	} | 	} | ||||||
| 	defer func() { | 	defer func() { | ||||||
| 		_ = r.Unset() | 		_ = r.Unset() | ||||||
|  | @ -70,36 +72,40 @@ func main() { | ||||||
| 	// create a new Cmd to provide shared dependencies and start components
 | 	// create a new Cmd to provide shared dependencies and start components
 | ||||||
| 	mgr, err := manager.New(cfg, manager.Options{Namespace: namespace}) | 	mgr, err := manager.New(cfg, manager.Options{Namespace: namespace}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		fatal(err, "failed to create manager") | 		fatal(errors.Wrap(err, "failed to create manager"), *debug) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	log.Log.Info("Registering Components.") | 	log.Log.Info("Registering Components.") | ||||||
| 
 | 
 | ||||||
| 	// setup Scheme for all resources
 | 	// setup Scheme for all resources
 | ||||||
| 	if err := apis.AddToScheme(mgr.GetScheme()); err != nil { | 	if err := apis.AddToScheme(mgr.GetScheme()); err != nil { | ||||||
| 		fatal(err, "failed to setup scheme") | 		fatal(errors.Wrap(err, "failed to setup scheme"), *debug) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// setup events
 | 	// setup events
 | ||||||
| 	events, err := event.New(cfg) | 	events, err := event.New(cfg, constants.OperatorName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		fatal(err, "failed to create manager") | 		fatal(errors.Wrap(err, "failed to create manager"), *debug) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// setup Jenkins controller
 | 	// setup Jenkins controller
 | ||||||
| 	if err := jenkins.Add(mgr, *local, *minikube, events); err != nil { | 	if err := jenkins.Add(mgr, *local, *minikube, events); err != nil { | ||||||
| 		fatal(err, "failed to setup controllers") | 		fatal(errors.Wrap(err, "failed to setup controllers"), *debug) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	log.Log.Info("Starting the Cmd.") | 	log.Log.Info("Starting the Cmd.") | ||||||
| 
 | 
 | ||||||
| 	// start the Cmd
 | 	// start the Cmd
 | ||||||
| 	if err := mgr.Start(signals.SetupSignalHandler()); err != nil { | 	if err := mgr.Start(signals.SetupSignalHandler()); err != nil { | ||||||
| 		fatal(err, "failed to start cmd") | 		fatal(errors.Wrap(err, "failed to start cmd"), *debug) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func fatal(err error, message string) { | func fatal(err error, debug bool) { | ||||||
| 	log.Log.Error(err, message) | 	if debug { | ||||||
|  | 		log.Log.Error(nil, fmt.Sprintf("%+v", err)) | ||||||
|  | 	} else { | ||||||
|  | 		log.Log.Error(nil, fmt.Sprintf("%s", err)) | ||||||
|  | 	} | ||||||
| 	os.Exit(-1) | 	os.Exit(-1) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -64,20 +64,13 @@ func (jenkins *jenkins) CreateOrUpdateJob(config, jobName string) (job *gojenkin | ||||||
| 	if isNotFoundError(err) { | 	if isNotFoundError(err) { | ||||||
| 		job, err = jenkins.CreateJob(config, jobName) | 		job, err = jenkins.CreateJob(config, jobName) | ||||||
| 		created = true | 		created = true | ||||||
| 		return | 		return job, true, errors.WithStack(err) | ||||||
| 	} else if err != nil { | 	} else if err != nil { | ||||||
| 		return | 		return job, false, errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = job.UpdateConfig(config) | 	err = job.UpdateConfig(config) | ||||||
| 	return | 	return job, false, errors.WithStack(err) | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func isNotFoundError(err error) bool { |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err.Error() == errorNotFound.Error() |  | ||||||
| 	} |  | ||||||
| 	return false |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // BuildJenkinsAPIUrl returns Jenkins API URL
 | // BuildJenkinsAPIUrl returns Jenkins API URL
 | ||||||
|  | @ -89,7 +82,7 @@ func BuildJenkinsAPIUrl(namespace, serviceName string, portNumber int, local, mi | ||||||
| 		cmd.Stdout = &out | 		cmd.Stdout = &out | ||||||
| 		err := cmd.Run() | 		err := cmd.Run() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return "", err | 			return "", errors.WithStack(err) | ||||||
| 		} | 		} | ||||||
| 		lines := strings.Split(out.String(), "\n") | 		lines := strings.Split(out.String(), "\n") | ||||||
| 		// First is for http, the second one is for Jenkins slaves communication
 | 		// First is for http, the second one is for Jenkins slaves communication
 | ||||||
|  | @ -135,3 +128,10 @@ func New(url, user, passwordOrToken string) (Jenkins, error) { | ||||||
| 
 | 
 | ||||||
| 	return jenkinsClient, nil | 	return jenkinsClient, nil | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func isNotFoundError(err error) bool { | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err.Error() == errorNotFound.Error() | ||||||
|  | 	} | ||||||
|  | 	return false | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"github.com/bndr/gojenkins" | 	"github.com/bndr/gojenkins" | ||||||
| 	"github.com/go-logr/logr" | 	"github.com/go-logr/logr" | ||||||
|  | 	stackerr "github.com/pkg/errors" | ||||||
| 	corev1 "k8s.io/api/core/v1" | 	corev1 "k8s.io/api/core/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/api/errors" | 	"k8s.io/apimachinery/pkg/api/errors" | ||||||
| 	apierrors "k8s.io/apimachinery/pkg/api/errors" | 	apierrors "k8s.io/apimachinery/pkg/api/errors" | ||||||
|  | @ -141,7 +142,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureResourcesRequiredForJenkinsPod | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) verifyPlugins(jenkinsClient jenkinsclient.Jenkins) (bool, error) { | func (r *ReconcileJenkinsBaseConfiguration) verifyPlugins(jenkinsClient jenkinsclient.Jenkins) (bool, error) { | ||||||
| 	allPluginsInJenkins, err := jenkinsClient.GetPlugins(fetchAllPlugins) | 	allPluginsInJenkins, err := jenkinsClient.GetPlugins(fetchAllPlugins) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, err | 		return false, stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var installedPlugins []string | 	var installedPlugins []string | ||||||
|  | @ -200,9 +201,9 @@ func (r *ReconcileJenkinsBaseConfiguration) createOperatorCredentialsSecret(meta | ||||||
| 	err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(r.jenkins), Namespace: r.jenkins.ObjectMeta.Namespace}, found) | 	err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(r.jenkins), Namespace: r.jenkins.ObjectMeta.Namespace}, found) | ||||||
| 
 | 
 | ||||||
| 	if err != nil && apierrors.IsNotFound(err) { | 	if err != nil && apierrors.IsNotFound(err) { | ||||||
| 		return r.createResource(resources.NewOperatorCredentialsSecret(meta, r.jenkins)) | 		return stackerr.WithStack(r.createResource(resources.NewOperatorCredentialsSecret(meta, r.jenkins))) | ||||||
| 	} else if err != nil && !apierrors.IsNotFound(err) { | 	} else if err != nil && !apierrors.IsNotFound(err) { | ||||||
| 		return err | 		return stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if found.Data[resources.OperatorCredentialsSecretUserNameKey] != nil && | 	if found.Data[resources.OperatorCredentialsSecretUserNameKey] != nil && | ||||||
|  | @ -210,7 +211,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createOperatorCredentialsSecret(meta | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return r.updateResource(resources.NewOperatorCredentialsSecret(meta, r.jenkins)) | 	return stackerr.WithStack(r.updateResource(resources.NewOperatorCredentialsSecret(meta, r.jenkins))) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) createScriptsConfigMap(meta metav1.ObjectMeta) error { | func (r *ReconcileJenkinsBaseConfiguration) createScriptsConfigMap(meta metav1.ObjectMeta) error { | ||||||
|  | @ -218,7 +219,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createScriptsConfigMap(meta metav1.O | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	return r.createOrUpdateResource(configMap) | 	return stackerr.WithStack(r.createOrUpdateResource(configMap)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) createInitConfigurationConfigMap(meta metav1.ObjectMeta) error { | func (r *ReconcileJenkinsBaseConfiguration) createInitConfigurationConfigMap(meta metav1.ObjectMeta) error { | ||||||
|  | @ -226,29 +227,26 @@ func (r *ReconcileJenkinsBaseConfiguration) createInitConfigurationConfigMap(met | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	return r.createOrUpdateResource(configMap) | 	return stackerr.WithStack(r.createOrUpdateResource(configMap)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) createBaseConfigurationConfigMap(meta metav1.ObjectMeta) error { | func (r *ReconcileJenkinsBaseConfiguration) createBaseConfigurationConfigMap(meta metav1.ObjectMeta) error { | ||||||
| 	configMap, err := resources.NewBaseConfigurationConfigMap(meta, r.jenkins) | 	configMap := resources.NewBaseConfigurationConfigMap(meta, r.jenkins) | ||||||
| 	if err != nil { | 	return stackerr.WithStack(r.createOrUpdateResource(configMap)) | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
| 	return r.createOrUpdateResource(configMap) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) createUserConfigurationConfigMap(meta metav1.ObjectMeta) error { | func (r *ReconcileJenkinsBaseConfiguration) createUserConfigurationConfigMap(meta metav1.ObjectMeta) error { | ||||||
| 	currentConfigMap := &corev1.ConfigMap{} | 	currentConfigMap := &corev1.ConfigMap{} | ||||||
| 	err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: resources.GetUserConfigurationConfigMapName(r.jenkins), Namespace: r.jenkins.Namespace}, currentConfigMap) | 	err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: resources.GetUserConfigurationConfigMapName(r.jenkins), Namespace: r.jenkins.Namespace}, currentConfigMap) | ||||||
| 	if err != nil && errors.IsNotFound(err) { | 	if err != nil && errors.IsNotFound(err) { | ||||||
| 		return r.k8sClient.Create(context.TODO(), resources.NewUserConfigurationConfigMap(r.jenkins)) | 		return stackerr.WithStack(r.k8sClient.Create(context.TODO(), resources.NewUserConfigurationConfigMap(r.jenkins))) | ||||||
| 	} else if err != nil { | 	} else if err != nil { | ||||||
| 		return err | 		return stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 	valid := r.verifyLabelsForWatchedResource(currentConfigMap) | 	valid := r.verifyLabelsForWatchedResource(currentConfigMap) | ||||||
| 	if !valid { | 	if !valid { | ||||||
| 		currentConfigMap.ObjectMeta.Labels = resources.BuildLabelsForWatchedResources(r.jenkins) | 		currentConfigMap.ObjectMeta.Labels = resources.BuildLabelsForWatchedResources(r.jenkins) | ||||||
| 		return r.k8sClient.Update(context.TODO(), currentConfigMap) | 		return stackerr.WithStack(r.k8sClient.Update(context.TODO(), currentConfigMap)) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
|  | @ -258,19 +256,19 @@ func (r *ReconcileJenkinsBaseConfiguration) createRBAC(meta metav1.ObjectMeta) e | ||||||
| 	serviceAccount := resources.NewServiceAccount(meta) | 	serviceAccount := resources.NewServiceAccount(meta) | ||||||
| 	err := r.createResource(serviceAccount) | 	err := r.createResource(serviceAccount) | ||||||
| 	if err != nil && !errors.IsAlreadyExists(err) { | 	if err != nil && !errors.IsAlreadyExists(err) { | ||||||
| 		return err | 		return stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	role := resources.NewRole(meta) | 	role := resources.NewRole(meta) | ||||||
| 	err = r.createOrUpdateResource(role) | 	err = r.createOrUpdateResource(role) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	roleBinding := resources.NewRoleBinding(meta) | 	roleBinding := resources.NewRoleBinding(meta) | ||||||
| 	err = r.createOrUpdateResource(roleBinding) | 	err = r.createOrUpdateResource(roleBinding) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
|  | @ -279,7 +277,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createRBAC(meta metav1.ObjectMeta) e | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) createService(meta metav1.ObjectMeta) error { | func (r *ReconcileJenkinsBaseConfiguration) createService(meta metav1.ObjectMeta) error { | ||||||
| 	err := r.createResource(resources.NewService(meta, r.minikube)) | 	err := r.createResource(resources.NewService(meta, r.minikube)) | ||||||
| 	if err != nil && !apierrors.IsAlreadyExists(err) { | 	if err != nil && !apierrors.IsAlreadyExists(err) { | ||||||
| 		return err | 		return stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
|  | @ -290,7 +288,7 @@ func (r *ReconcileJenkinsBaseConfiguration) getJenkinsMasterPod(meta metav1.Obje | ||||||
| 	currentJenkinsMasterPod := &corev1.Pod{} | 	currentJenkinsMasterPod := &corev1.Pod{} | ||||||
| 	err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: jenkinsMasterPod.Name, Namespace: jenkinsMasterPod.Namespace}, currentJenkinsMasterPod) | 	err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: jenkinsMasterPod.Name, Namespace: jenkinsMasterPod.Namespace}, currentJenkinsMasterPod) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err // don't wrap error
 | ||||||
| 	} | 	} | ||||||
| 	return currentJenkinsMasterPod, nil | 	return currentJenkinsMasterPod, nil | ||||||
| } | } | ||||||
|  | @ -303,16 +301,16 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsMasterPod(meta metav1.O | ||||||
| 		r.logger.Info(fmt.Sprintf("Creating a new Jenkins Master Pod %s/%s", jenkinsMasterPod.Namespace, jenkinsMasterPod.Name)) | 		r.logger.Info(fmt.Sprintf("Creating a new Jenkins Master Pod %s/%s", jenkinsMasterPod.Namespace, jenkinsMasterPod.Name)) | ||||||
| 		err = r.createResource(jenkinsMasterPod) | 		err = r.createResource(jenkinsMasterPod) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return reconcile.Result{}, err | 			return reconcile.Result{}, stackerr.WithStack(err) | ||||||
| 		} | 		} | ||||||
| 		r.jenkins.Status = v1alpha1.JenkinsStatus{} | 		r.jenkins.Status = v1alpha1.JenkinsStatus{} | ||||||
| 		err = r.updateResource(r.jenkins) | 		err = r.updateResource(r.jenkins) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return reconcile.Result{}, err | 			return reconcile.Result{}, err // don't wrap error
 | ||||||
| 		} | 		} | ||||||
| 		return reconcile.Result{}, nil | 		return reconcile.Result{}, nil | ||||||
| 	} else if err != nil && !errors.IsNotFound(err) { | 	} else if err != nil && !errors.IsNotFound(err) { | ||||||
| 		return reconcile.Result{}, err | 		return reconcile.Result{}, stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Recreate pod
 | 	// Recreate pod
 | ||||||
|  | @ -357,7 +355,7 @@ func (r *ReconcileJenkinsBaseConfiguration) restartJenkinsMasterPod(meta metav1. | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	return r.k8sClient.Delete(context.TODO(), currentJenkinsMasterPod) | 	return stackerr.WithStack(r.k8sClient.Delete(context.TODO(), currentJenkinsMasterPod)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) waitForJenkins(meta metav1.ObjectMeta) (reconcile.Result, error) { | func (r *ReconcileJenkinsBaseConfiguration) waitForJenkins(meta metav1.ObjectMeta) (reconcile.Result, error) { | ||||||
|  | @ -397,7 +395,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient(meta metav1.Obje | ||||||
| 	credentialsSecret := &corev1.Secret{} | 	credentialsSecret := &corev1.Secret{} | ||||||
| 	err = r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(r.jenkins), Namespace: r.jenkins.ObjectMeta.Namespace}, credentialsSecret) | 	err = r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(r.jenkins), Namespace: r.jenkins.ObjectMeta.Namespace}, credentialsSecret) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 	currentJenkinsMasterPod, err := r.getJenkinsMasterPod(meta) | 	currentJenkinsMasterPod, err := r.getJenkinsMasterPod(meta) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  | @ -437,7 +435,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient(meta metav1.Obje | ||||||
| 		credentialsSecret.Data[resources.OperatorCredentialsSecretTokenCreationKey] = now | 		credentialsSecret.Data[resources.OperatorCredentialsSecretTokenCreationKey] = now | ||||||
| 		err = r.updateResource(credentialsSecret) | 		err = r.updateResource(credentialsSecret) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, err | 			return nil, stackerr.WithStack(err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -459,7 +457,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureBaseConfiguration(jenkinsClien | ||||||
| 	namespaceName := types.NamespacedName{Namespace: r.jenkins.Namespace, Name: resources.GetBaseConfigurationConfigMapName(r.jenkins)} | 	namespaceName := types.NamespacedName{Namespace: r.jenkins.Namespace, Name: resources.GetBaseConfigurationConfigMapName(r.jenkins)} | ||||||
| 	err = r.k8sClient.Get(context.TODO(), namespaceName, configuration) | 	err = r.k8sClient.Get(context.TODO(), namespaceName, configuration) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return reconcile.Result{}, err | 		return reconcile.Result{}, stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	done, err := groovyClient.EnsureGroovyJob(configuration.Data, r.jenkins) | 	done, err := groovyClient.EnsureGroovyJob(configuration.Data, r.jenkins) | ||||||
|  |  | ||||||
|  | @ -2,8 +2,8 @@ package base | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" |  | ||||||
| 
 | 
 | ||||||
|  | 	stackerr "github.com/pkg/errors" | ||||||
| 	"k8s.io/apimachinery/pkg/api/errors" | 	"k8s.io/apimachinery/pkg/api/errors" | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
|  | @ -13,33 +13,33 @@ import ( | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) createResource(obj metav1.Object) error { | func (r *ReconcileJenkinsBaseConfiguration) createResource(obj metav1.Object) error { | ||||||
| 	runtimeObj, ok := obj.(runtime.Object) | 	runtimeObj, ok := obj.(runtime.Object) | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return fmt.Errorf("is not a %T a runtime.Object", obj) | 		return stackerr.Errorf("is not a %T a runtime.Object", obj) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Set Jenkins instance as the owner and controller
 | 	// Set Jenkins instance as the owner and controller
 | ||||||
| 	if err := controllerutil.SetControllerReference(r.jenkins, obj, r.scheme); err != nil { | 	if err := controllerutil.SetControllerReference(r.jenkins, obj, r.scheme); err != nil { | ||||||
| 		return err | 		return stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return r.k8sClient.Create(context.TODO(), runtimeObj) | 	return r.k8sClient.Create(context.TODO(), runtimeObj) // don't wrap error
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) updateResource(obj metav1.Object) error { | func (r *ReconcileJenkinsBaseConfiguration) updateResource(obj metav1.Object) error { | ||||||
| 	runtimeObj, ok := obj.(runtime.Object) | 	runtimeObj, ok := obj.(runtime.Object) | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return fmt.Errorf("is not a %T a runtime.Object", obj) | 		return stackerr.Errorf("is not a %T a runtime.Object", obj) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// set Jenkins instance as the owner and controller, don't check error(can be already set)
 | 	// set Jenkins instance as the owner and controller, don't check error(can be already set)
 | ||||||
| 	_ = controllerutil.SetControllerReference(r.jenkins, obj, r.scheme) | 	_ = controllerutil.SetControllerReference(r.jenkins, obj, r.scheme) | ||||||
| 
 | 
 | ||||||
| 	return r.k8sClient.Update(context.TODO(), runtimeObj) | 	return r.k8sClient.Update(context.TODO(), runtimeObj) // don't wrap error
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) createOrUpdateResource(obj metav1.Object) error { | func (r *ReconcileJenkinsBaseConfiguration) createOrUpdateResource(obj metav1.Object) error { | ||||||
| 	runtimeObj, ok := obj.(runtime.Object) | 	runtimeObj, ok := obj.(runtime.Object) | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return fmt.Errorf("is not a %T a runtime.Object", obj) | 		return stackerr.Errorf("is not a %T a runtime.Object", obj) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// set Jenkins instance as the owner and controller, don't check error(can be already set)
 | 	// set Jenkins instance as the owner and controller, don't check error(can be already set)
 | ||||||
|  | @ -49,7 +49,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createOrUpdateResource(obj metav1.Ob | ||||||
| 	if err != nil && errors.IsAlreadyExists(err) { | 	if err != nil && errors.IsAlreadyExists(err) { | ||||||
| 		return r.updateResource(obj) | 		return r.updateResource(obj) | ||||||
| 	} else if err != nil && !errors.IsAlreadyExists(err) { | 	} else if err != nil && !errors.IsAlreadyExists(err) { | ||||||
| 		return err | 		return stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
|  |  | ||||||
|  | @ -167,7 +167,7 @@ func GetBaseConfigurationConfigMapName(jenkins *v1alpha1.Jenkins) string { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NewBaseConfigurationConfigMap builds Kubernetes config map used to base configuration
 | // NewBaseConfigurationConfigMap builds Kubernetes config map used to base configuration
 | ||||||
| func NewBaseConfigurationConfigMap(meta metav1.ObjectMeta, jenkins *v1alpha1.Jenkins) (*corev1.ConfigMap, error) { | func NewBaseConfigurationConfigMap(meta metav1.ObjectMeta, jenkins *v1alpha1.Jenkins) *corev1.ConfigMap { | ||||||
| 	meta.Name = GetBaseConfigurationConfigMapName(jenkins) | 	meta.Name = GetBaseConfigurationConfigMapName(jenkins) | ||||||
| 
 | 
 | ||||||
| 	return &corev1.ConfigMap{ | 	return &corev1.ConfigMap{ | ||||||
|  | @ -183,5 +183,5 @@ func NewBaseConfigurationConfigMap(meta metav1.ObjectMeta, jenkins *v1alpha1.Jen | ||||||
| 				jenkins.ObjectMeta.Namespace, GetResourceName(jenkins), HTTPPortInt), | 				jenkins.ObjectMeta.Namespace, GetResourceName(jenkins), HTTPPortInt), | ||||||
| 			"7-configure-views.groovy": configureViews, | 			"7-configure-views.groovy": configureViews, | ||||||
| 		}, | 		}, | ||||||
| 	}, nil | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -3,13 +3,15 @@ package resources | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"text/template" | 	"text/template" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pkg/errors" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // render executes a parsed template (go-template) with configuration from data
 | // render executes a parsed template (go-template) with configuration from data
 | ||||||
| func render(template *template.Template, data interface{}) (string, error) { | func render(template *template.Template, data interface{}) (string, error) { | ||||||
| 	var buffer bytes.Buffer | 	var buffer bytes.Buffer | ||||||
| 	if err := template.Execute(&buffer, data); err != nil { | 	if err := template.Execute(&buffer, data); err != nil { | ||||||
| 		return "", err | 		return "", errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return buffer.String(), nil | 	return buffer.String(), nil | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ import ( | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/jobs" | 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/jobs" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-logr/logr" | 	"github.com/go-logr/logr" | ||||||
|  | 	"github.com/pkg/errors" | ||||||
| 	corev1 "k8s.io/api/core/v1" | 	corev1 "k8s.io/api/core/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
| 	k8s "sigs.k8s.io/controller-runtime/pkg/client" | 	k8s "sigs.k8s.io/controller-runtime/pkg/client" | ||||||
|  | @ -73,7 +74,7 @@ func (r *ReconcileUserConfiguration) ensureSeedJobs() (reconcile.Result, error) | ||||||
| 			return reconcile.Result{}, nil | 			return reconcile.Result{}, nil | ||||||
| 		} | 		} | ||||||
| 		// unexpected error - requeue reconciliation loop
 | 		// unexpected error - requeue reconciliation loop
 | ||||||
| 		return reconcile.Result{}, err | 		return reconcile.Result{}, errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 	// build not finished yet - requeue reconciliation loop with timeout
 | 	// build not finished yet - requeue reconciliation loop with timeout
 | ||||||
| 	if !done { | 	if !done { | ||||||
|  | @ -94,7 +95,7 @@ func (r *ReconcileUserConfiguration) ensureUserConfiguration(jenkinsClient jenki | ||||||
| 	namespaceName := types.NamespacedName{Namespace: r.jenkins.Namespace, Name: resources.GetUserConfigurationConfigMapName(r.jenkins)} | 	namespaceName := types.NamespacedName{Namespace: r.jenkins.Namespace, Name: resources.GetUserConfigurationConfigMapName(r.jenkins)} | ||||||
| 	err = r.k8sClient.Get(context.TODO(), namespaceName, configuration) | 	err = r.k8sClient.Get(context.TODO(), namespaceName, configuration) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return reconcile.Result{}, err | 		return reconcile.Result{}, errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	done, err := groovyClient.EnsureGroovyJob(configuration.Data, r.jenkins) | 	done, err := groovyClient.EnsureGroovyJob(configuration.Data, r.jenkins) | ||||||
|  |  | ||||||
|  | @ -4,13 +4,13 @@ import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"crypto/x509" | 	"crypto/x509" | ||||||
| 	"encoding/pem" | 	"encoding/pem" | ||||||
| 	"errors" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkinsio/v1alpha1" | 	"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkinsio/v1alpha1" | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | ||||||
| 
 | 
 | ||||||
|  | 	stackerr "github.com/pkg/errors" | ||||||
| 	"k8s.io/api/core/v1" | 	"k8s.io/api/core/v1" | ||||||
| 	apierrors "k8s.io/apimachinery/pkg/api/errors" | 	apierrors "k8s.io/apimachinery/pkg/api/errors" | ||||||
| 	"k8s.io/apimachinery/pkg/types" | 	"k8s.io/apimachinery/pkg/types" | ||||||
|  | @ -55,7 +55,7 @@ func (r *ReconcileUserConfiguration) validateSeedJobs(jenkins *v1alpha1.Jenkins) | ||||||
| 					logger.Info("secret not found") | 					logger.Info("secret not found") | ||||||
| 					valid = false | 					valid = false | ||||||
| 				} else if err != nil { | 				} else if err != nil { | ||||||
| 					return false, err | 					return false, stackerr.WithStack(err) | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				privateKey := string(deployKeySecret.Data[seedJob.PrivateKey.SecretKeyRef.Key]) | 				privateKey := string(deployKeySecret.Data[seedJob.PrivateKey.SecretKeyRef.Key]) | ||||||
|  | @ -77,17 +77,17 @@ func (r *ReconcileUserConfiguration) validateSeedJobs(jenkins *v1alpha1.Jenkins) | ||||||
| func validatePrivateKey(privateKey string) error { | func validatePrivateKey(privateKey string) error { | ||||||
| 	block, _ := pem.Decode([]byte(privateKey)) | 	block, _ := pem.Decode([]byte(privateKey)) | ||||||
| 	if block == nil { | 	if block == nil { | ||||||
| 		return errors.New("failed to decode PEM block") | 		return stackerr.New("failed to decode PEM block") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) | 	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = priv.Validate() | 	err = priv.Validate() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return stackerr.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ import ( | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-logr/logr" | 	"github.com/go-logr/logr" | ||||||
|  | 	"github.com/pkg/errors" | ||||||
| 	corev1 "k8s.io/api/core/v1" | 	corev1 "k8s.io/api/core/v1" | ||||||
| 	apierrors "k8s.io/apimachinery/pkg/api/errors" | 	apierrors "k8s.io/apimachinery/pkg/api/errors" | ||||||
| 	"k8s.io/apimachinery/pkg/api/resource" | 	"k8s.io/apimachinery/pkg/api/resource" | ||||||
|  | @ -57,13 +58,13 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { | ||||||
| 	// Create a new controller
 | 	// Create a new controller
 | ||||||
| 	c, err := controller.New("jenkins-controller", mgr, controller.Options{Reconciler: r}) | 	c, err := controller.New("jenkins-controller", mgr, controller.Options{Reconciler: r}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Watch for changes to primary resource Jenkins
 | 	// Watch for changes to primary resource Jenkins
 | ||||||
| 	err = c.Watch(&source.Kind{Type: &v1alpha1.Jenkins{}}, &handler.EnqueueRequestForObject{}) | 	err = c.Watch(&source.Kind{Type: &v1alpha1.Jenkins{}}, &handler.EnqueueRequestForObject{}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// Watch for changes to secondary resource Pods and requeue the owner Jenkins
 | 	// Watch for changes to secondary resource Pods and requeue the owner Jenkins
 | ||||||
|  | @ -72,18 +73,18 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error { | ||||||
| 		OwnerType:    &v1alpha1.Jenkins{}, | 		OwnerType:    &v1alpha1.Jenkins{}, | ||||||
| 	}) | 	}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	jenkinsHandler := &enqueueRequestForJenkins{} | 	jenkinsHandler := &enqueueRequestForJenkins{} | ||||||
| 	err = c.Watch(&source.Kind{Type: &corev1.Secret{}}, jenkinsHandler) | 	err = c.Watch(&source.Kind{Type: &corev1.Secret{}}, jenkinsHandler) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = c.Watch(&source.Kind{Type: &corev1.ConfigMap{}}, jenkinsHandler) | 	err = c.Watch(&source.Kind{Type: &corev1.ConfigMap{}}, jenkinsHandler) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
|  | @ -109,7 +110,11 @@ func (r *ReconcileJenkins) Reconcile(request reconcile.Request) (reconcile.Resul | ||||||
| 		logger.V(log.VWarn).Info(err.Error()) | 		logger.V(log.VWarn).Info(err.Error()) | ||||||
| 		return reconcile.Result{Requeue: true}, nil | 		return reconcile.Result{Requeue: true}, nil | ||||||
| 	} else if err != nil { | 	} else if err != nil { | ||||||
|  | 		if log.Debug { | ||||||
| 			logger.V(log.VWarn).Info(fmt.Sprintf("Reconcile loop failed: %+v", err)) | 			logger.V(log.VWarn).Info(fmt.Sprintf("Reconcile loop failed: %+v", err)) | ||||||
|  | 		} else { | ||||||
|  | 			logger.V(log.VWarn).Info(fmt.Sprintf("Reconcile loop failed: %s", err)) | ||||||
|  | 		} | ||||||
| 		return reconcile.Result{Requeue: true}, nil | 		return reconcile.Result{Requeue: true}, nil | ||||||
| 	} | 	} | ||||||
| 	return result, nil | 	return result, nil | ||||||
|  | @ -127,7 +132,7 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg | ||||||
| 			return reconcile.Result{}, nil | 			return reconcile.Result{}, nil | ||||||
| 		} | 		} | ||||||
| 		// Error reading the object - requeue the request.
 | 		// Error reading the object - requeue the request.
 | ||||||
| 		return reconcile.Result{}, err | 		return reconcile.Result{}, errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	err = r.setDefaults(jenkins, logger) | 	err = r.setDefaults(jenkins, logger) | ||||||
|  | @ -161,7 +166,7 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg | ||||||
| 		jenkins.Status.BaseConfigurationCompletedTime = &now | 		jenkins.Status.BaseConfigurationCompletedTime = &now | ||||||
| 		err = r.client.Update(context.TODO(), jenkins) | 		err = r.client.Update(context.TODO(), jenkins) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return reconcile.Result{}, err | 			return reconcile.Result{}, errors.WithStack(err) | ||||||
| 		} | 		} | ||||||
| 		logger.Info("Base configuration phase is complete") | 		logger.Info("Base configuration phase is complete") | ||||||
| 		r.events.Emit(jenkins, event.TypeNormal, reasonBaseConfigurationSuccess, "Base configuration completed") | 		r.events.Emit(jenkins, event.TypeNormal, reasonBaseConfigurationSuccess, "Base configuration completed") | ||||||
|  | @ -192,7 +197,7 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg | ||||||
| 		jenkins.Status.UserConfigurationCompletedTime = &now | 		jenkins.Status.UserConfigurationCompletedTime = &now | ||||||
| 		err = r.client.Update(context.TODO(), jenkins) | 		err = r.client.Update(context.TODO(), jenkins) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return reconcile.Result{}, err | 			return reconcile.Result{}, errors.WithStack(err) | ||||||
| 		} | 		} | ||||||
| 		logger.Info("User configuration phase is complete") | 		logger.Info("User configuration phase is complete") | ||||||
| 		r.events.Emit(jenkins, event.TypeNormal, reasonUserConfigurationSuccess, "User configuration completed") | 		r.events.Emit(jenkins, event.TypeNormal, reasonUserConfigurationSuccess, "User configuration completed") | ||||||
|  | @ -241,7 +246,7 @@ func (r *ReconcileJenkins) setDefaults(jenkins *v1alpha1.Jenkins, logger logr.Lo | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if changed { | 	if changed { | ||||||
| 		return r.client.Update(context.TODO(), jenkins) | 		return errors.WithStack(r.client.Update(context.TODO(), jenkins)) | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ package jobs | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"errors" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
|  | @ -11,21 +10,22 @@ import ( | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-logr/logr" | 	"github.com/go-logr/logr" | ||||||
|  | 	"github.com/pkg/errors" | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	k8s "sigs.k8s.io/controller-runtime/pkg/client" | 	k8s "sigs.k8s.io/controller-runtime/pkg/client" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
| 	// ErrorUnexpectedBuildStatus - this is custom error returned when jenkins build has unexpected status
 | 	// ErrorUnexpectedBuildStatus - this is custom error returned when jenkins build has unexpected status
 | ||||||
| 	ErrorUnexpectedBuildStatus = errors.New("unexpected build status") | 	ErrorUnexpectedBuildStatus = fmt.Errorf("unexpected build status") | ||||||
| 	// ErrorBuildFailed - this is custom error returned when jenkins build has failed
 | 	// ErrorBuildFailed - this is custom error returned when jenkins build has failed
 | ||||||
| 	ErrorBuildFailed = errors.New("build failed") | 	ErrorBuildFailed = fmt.Errorf("build failed") | ||||||
| 	// ErrorAbortBuildFailed - this is custom error returned when jenkins build couldn't be aborted
 | 	// ErrorAbortBuildFailed - this is custom error returned when jenkins build couldn't be aborted
 | ||||||
| 	ErrorAbortBuildFailed = errors.New("build abort failed") | 	ErrorAbortBuildFailed = fmt.Errorf("build abort failed") | ||||||
| 	// ErrorUnrecoverableBuildFailed - this is custom error returned when jenkins build has failed and cannot be recovered
 | 	// ErrorUnrecoverableBuildFailed - this is custom error returned when jenkins build has failed and cannot be recovered
 | ||||||
| 	ErrorUnrecoverableBuildFailed = errors.New("build failed and cannot be recovered") | 	ErrorUnrecoverableBuildFailed = fmt.Errorf("build failed and cannot be recovered") | ||||||
| 	// ErrorNotFound - this is error returned when jenkins build couldn't be found
 | 	// ErrorNotFound - this is error returned when jenkins build couldn't be found
 | ||||||
| 	ErrorNotFound = errors.New("404") | 	ErrorNotFound = fmt.Errorf("404") | ||||||
| 	// BuildRetires - determines max amount of retires for failed build
 | 	// BuildRetires - determines max amount of retires for failed build
 | ||||||
| 	BuildRetires = 3 | 	BuildRetires = 3 | ||||||
| ) | ) | ||||||
|  | @ -54,11 +54,7 @@ func New(jenkinsClient client.Jenkins, k8sClient k8s.Client, logger logr.Logger) | ||||||
| func (jobs *Jobs) EnsureBuildJob(jobName, hash string, parameters map[string]string, jenkins *v1alpha1.Jenkins, preserveStatus bool) (done bool, err error) { | func (jobs *Jobs) EnsureBuildJob(jobName, hash string, parameters map[string]string, jenkins *v1alpha1.Jenkins, preserveStatus bool) (done bool, err error) { | ||||||
| 	jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Ensuring build, name:'%s' hash:'%s'", jobName, hash)) | 	jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Ensuring build, name:'%s' hash:'%s'", jobName, hash)) | ||||||
| 
 | 
 | ||||||
| 	build, err := jobs.getBuildFromStatus(jobName, hash, jenkins) | 	build := jobs.getBuildFromStatus(jobName, hash, jenkins) | ||||||
| 	if err != nil { |  | ||||||
| 		return false, err |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if build != nil { | 	if build != nil { | ||||||
| 		jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Build exists in status, %+v", build)) | 		jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Build exists in status, %+v", build)) | ||||||
| 		switch build.Status { | 		switch build.Status { | ||||||
|  | @ -86,16 +82,16 @@ func (jobs *Jobs) EnsureBuildJob(jobName, hash string, parameters map[string]str | ||||||
| 	return jobs.buildJob(newBuild, parameters, jenkins) | 	return jobs.buildJob(newBuild, parameters, jenkins) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (jobs *Jobs) getBuildFromStatus(jobName string, hash string, jenkins *v1alpha1.Jenkins) (*v1alpha1.Build, error) { | func (jobs *Jobs) getBuildFromStatus(jobName string, hash string, jenkins *v1alpha1.Jenkins) *v1alpha1.Build { | ||||||
| 	if jenkins != nil { | 	if jenkins != nil { | ||||||
| 		builds := jenkins.Status.Builds | 		builds := jenkins.Status.Builds | ||||||
| 		for _, build := range builds { | 		for _, build := range builds { | ||||||
| 			if build.JobName == jobName && build.Hash == hash { | 			if build.JobName == jobName && build.Hash == hash { | ||||||
| 				return &build, nil | 				return &build | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return nil, nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (jobs *Jobs) ensureSuccessBuild(build v1alpha1.Build, jenkins *v1alpha1.Jenkins, preserveStatus bool) (bool, error) { | func (jobs *Jobs) ensureSuccessBuild(build v1alpha1.Build, jenkins *v1alpha1.Jenkins, preserveStatus bool) (bool, error) { | ||||||
|  | @ -103,7 +99,6 @@ func (jobs *Jobs) ensureSuccessBuild(build v1alpha1.Build, jenkins *v1alpha1.Jen | ||||||
| 
 | 
 | ||||||
| 	if !preserveStatus { | 	if !preserveStatus { | ||||||
| 		err := jobs.removeBuildFromStatus(build, jenkins) | 		err := jobs.removeBuildFromStatus(build, jenkins) | ||||||
| 		jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Removing build from status, %+v", build)) |  | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			jobs.logger.V(log.VWarn).Info(fmt.Sprintf("Couldn't remove build from status, %+v", build)) | 			jobs.logger.V(log.VWarn).Info(fmt.Sprintf("Couldn't remove build from status, %+v", build)) | ||||||
| 			return false, err | 			return false, err | ||||||
|  | @ -122,7 +117,7 @@ func (jobs *Jobs) ensureRunningBuild(build v1alpha1.Build, jenkins *v1alpha1.Jen | ||||||
| 		return false, nil | 		return false, nil | ||||||
| 	} else if err != nil { | 	} else if err != nil { | ||||||
| 		jobs.logger.V(log.VWarn).Info(fmt.Sprintf("Couldn't get jenkins build, %+v", build)) | 		jobs.logger.V(log.VWarn).Info(fmt.Sprintf("Couldn't get jenkins build, %+v", build)) | ||||||
| 		return false, err | 		return false, errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if jenkinsBuild.GetResult() != "" { | 	if jenkinsBuild.GetResult() != "" { | ||||||
|  | @ -166,7 +161,6 @@ func (jobs *Jobs) ensureFailedBuild(build v1alpha1.Build, jenkins *v1alpha1.Jenk | ||||||
| 	jobs.logger.V(log.VWarn).Info(fmt.Sprintf("The retries limit was reached , %+v", build)) | 	jobs.logger.V(log.VWarn).Info(fmt.Sprintf("The retries limit was reached , %+v", build)) | ||||||
| 
 | 
 | ||||||
| 	if !preserveStatus { | 	if !preserveStatus { | ||||||
| 		jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Removing build from status, %+v", build)) |  | ||||||
| 		err := jobs.removeBuildFromStatus(build, jenkins) | 		err := jobs.removeBuildFromStatus(build, jenkins) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			jobs.logger.V(log.VWarn).Info(fmt.Sprintf("Couldn't remove build from status, %+v", build)) | 			jobs.logger.V(log.VWarn).Info(fmt.Sprintf("Couldn't remove build from status, %+v", build)) | ||||||
|  | @ -181,17 +175,17 @@ func (jobs *Jobs) ensureExpiredBuild(build v1alpha1.Build, jenkins *v1alpha1.Jen | ||||||
| 
 | 
 | ||||||
| 	jenkinsBuild, err := jobs.jenkinsClient.GetBuild(build.JobName, build.Number) | 	jenkinsBuild, err := jobs.jenkinsClient.GetBuild(build.JobName, build.Number) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, err | 		return false, errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	_, err = jenkinsBuild.Stop() | 	_, err = jenkinsBuild.Stop() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, err | 		return false, errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	jenkinsBuild, err = jobs.jenkinsClient.GetBuild(build.JobName, build.Number) | 	jenkinsBuild, err = jobs.jenkinsClient.GetBuild(build.JobName, build.Number) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, err | 		return false, errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if v1alpha1.BuildStatus(jenkinsBuild.GetResult()) != v1alpha1.BuildAbortedStatus { | 	if v1alpha1.BuildStatus(jenkinsBuild.GetResult()) != v1alpha1.BuildAbortedStatus { | ||||||
|  | @ -206,7 +200,6 @@ func (jobs *Jobs) ensureExpiredBuild(build v1alpha1.Build, jenkins *v1alpha1.Jen | ||||||
| 	// TODO(antoniaklja) clean up k8s resources
 | 	// TODO(antoniaklja) clean up k8s resources
 | ||||||
| 
 | 
 | ||||||
| 	if !preserveStatus { | 	if !preserveStatus { | ||||||
| 		jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Removing build from status, %+v", build)) |  | ||||||
| 		err = jobs.removeBuildFromStatus(build, jenkins) | 		err = jobs.removeBuildFromStatus(build, jenkins) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			jobs.logger.V(log.VWarn).Info(fmt.Sprintf("Couldn't remove build from status, %+v", build)) | 			jobs.logger.V(log.VWarn).Info(fmt.Sprintf("Couldn't remove build from status, %+v", build)) | ||||||
|  | @ -218,6 +211,7 @@ func (jobs *Jobs) ensureExpiredBuild(build v1alpha1.Build, jenkins *v1alpha1.Jen | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (jobs *Jobs) removeBuildFromStatus(build v1alpha1.Build, jenkins *v1alpha1.Jenkins) error { | func (jobs *Jobs) removeBuildFromStatus(build v1alpha1.Build, jenkins *v1alpha1.Jenkins) error { | ||||||
|  | 	jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Removing build from status, %+v", build)) | ||||||
| 	builds := make([]v1alpha1.Build, len(jenkins.Status.Builds)) | 	builds := make([]v1alpha1.Build, len(jenkins.Status.Builds)) | ||||||
| 	for _, existingBuild := range jenkins.Status.Builds { | 	for _, existingBuild := range jenkins.Status.Builds { | ||||||
| 		if existingBuild.JobName != build.JobName && existingBuild.Hash != build.Hash { | 		if existingBuild.JobName != build.JobName && existingBuild.Hash != build.Hash { | ||||||
|  | @ -227,7 +221,7 @@ func (jobs *Jobs) removeBuildFromStatus(build v1alpha1.Build, jenkins *v1alpha1. | ||||||
| 	jenkins.Status.Builds = builds | 	jenkins.Status.Builds = builds | ||||||
| 	err := jobs.k8sClient.Update(context.TODO(), jenkins) | 	err := jobs.k8sClient.Update(context.TODO(), jenkins) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err // don't wrap because apierrors.IsConflict(err) won't work in jenkins_controller
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
|  | @ -238,7 +232,7 @@ func (jobs *Jobs) buildJob(build v1alpha1.Build, parameters map[string]string, j | ||||||
| 	job, err := jobs.jenkinsClient.GetJob(build.JobName) | 	job, err := jobs.jenkinsClient.GetJob(build.JobName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		jobs.logger.V(log.VWarn).Info(fmt.Sprintf("Couldn't find jenkins job, %+v", build)) | 		jobs.logger.V(log.VWarn).Info(fmt.Sprintf("Couldn't find jenkins job, %+v", build)) | ||||||
| 		return false, err | 		return false, errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 	nextBuildNumber := job.GetDetails().NextBuildNumber | 	nextBuildNumber := job.GetDetails().NextBuildNumber | ||||||
| 
 | 
 | ||||||
|  | @ -246,7 +240,7 @@ func (jobs *Jobs) buildJob(build v1alpha1.Build, parameters map[string]string, j | ||||||
| 	_, err = jobs.jenkinsClient.BuildJob(build.JobName, parameters) | 	_, err = jobs.jenkinsClient.BuildJob(build.JobName, parameters) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		jobs.logger.V(log.VWarn).Info(fmt.Sprintf("Couldn't run build, %+v", build)) | 		jobs.logger.V(log.VWarn).Info(fmt.Sprintf("Couldn't run build, %+v", build)) | ||||||
| 		return false, err | 		return false, errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	build.Status = v1alpha1.BuildRunningStatus | 	build.Status = v1alpha1.BuildRunningStatus | ||||||
|  | @ -281,7 +275,7 @@ func (jobs *Jobs) updateBuildStatus(build v1alpha1.Build, jenkins *v1alpha1.Jenk | ||||||
| 	} | 	} | ||||||
| 	err := jobs.k8sClient.Update(context.TODO(), jenkins) | 	err := jobs.k8sClient.Update(context.TODO(), jenkins) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err // don't wrap because apierrors.IsConflict(err) won't work in jenkins_controller
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nil | 	return nil | ||||||
|  |  | ||||||
|  | @ -5,6 +5,8 @@ import ( | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | 	"github.com/jenkinsci/kubernetes-operator/pkg/log" | ||||||
|  | 
 | ||||||
|  | 	"github.com/pkg/errors" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Plugin represents jenkins plugin
 | // Plugin represents jenkins plugin
 | ||||||
|  | @ -22,7 +24,7 @@ func (p Plugin) String() string { | ||||||
| func New(nameWithVersion string) (*Plugin, error) { | func New(nameWithVersion string) (*Plugin, error) { | ||||||
| 	val := strings.SplitN(nameWithVersion, ":", 2) | 	val := strings.SplitN(nameWithVersion, ":", 2) | ||||||
| 	if val == nil || len(val) != 2 { | 	if val == nil || len(val) != 2 { | ||||||
| 		return nil, fmt.Errorf("invalid plugin format '%s'", nameWithVersion) | 		return nil, errors.Errorf("invalid plugin format '%s'", nameWithVersion) | ||||||
| 	} | 	} | ||||||
| 	return &Plugin{ | 	return &Plugin{ | ||||||
| 		Name:    val[0], | 		Name:    val[0], | ||||||
|  |  | ||||||
|  | @ -9,8 +9,7 @@ import ( | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestVerifyDependencies(t *testing.T) { | func TestVerifyDependencies(t *testing.T) { | ||||||
| 	debug := false | 	log.SetupLogger(false) | ||||||
| 	log.SetupLogger(&debug) |  | ||||||
| 
 | 
 | ||||||
| 	t.Run("happy, single root plugin with one dependent plugin", func(t *testing.T) { | 	t.Run("happy, single root plugin with one dependent plugin", func(t *testing.T) { | ||||||
| 		basePlugins := map[Plugin][]Plugin{ | 		basePlugins := map[Plugin][]Plugin{ | ||||||
|  |  | ||||||
|  | @ -3,8 +3,7 @@ package event | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
| 	"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants" | 	"github.com/pkg/errors" | ||||||
| 
 |  | ||||||
| 	"k8s.io/api/core/v1" | 	"k8s.io/api/core/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
| 	"k8s.io/client-go/kubernetes" | 	"k8s.io/client-go/kubernetes" | ||||||
|  | @ -38,8 +37,8 @@ type recorder struct { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // New returns recorder used to emit events
 | // New returns recorder used to emit events
 | ||||||
| func New(config *rest.Config) (Recorder, error) { | func New(config *rest.Config, component string) (Recorder, error) { | ||||||
| 	eventRecorder, err := initializeEventRecorder(config) | 	eventRecorder, err := initializeEventRecorder(config, component) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | @ -49,10 +48,10 @@ func New(config *rest.Config) (Recorder, error) { | ||||||
| 	}, nil | 	}, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func initializeEventRecorder(config *rest.Config) (record.EventRecorder, error) { | func initializeEventRecorder(config *rest.Config, component string) (record.EventRecorder, error) { | ||||||
| 	client, err := kubernetes.NewForConfig(config) | 	client, err := kubernetes.NewForConfig(config) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, errors.WithStack(err) | ||||||
| 	} | 	} | ||||||
| 	eventBroadcaster := record.NewBroadcaster() | 	eventBroadcaster := record.NewBroadcaster() | ||||||
| 	//eventBroadcaster.StartLogging(glog.Infof) TODO integrate with proper logger
 | 	//eventBroadcaster.StartLogging(glog.Infof) TODO integrate with proper logger
 | ||||||
|  | @ -61,8 +60,8 @@ func initializeEventRecorder(config *rest.Config) (record.EventRecorder, error) | ||||||
| 			Interface: client.CoreV1().Events("")}) | 			Interface: client.CoreV1().Events("")}) | ||||||
| 	eventRecorder := eventBroadcaster.NewRecorder( | 	eventRecorder := eventBroadcaster.NewRecorder( | ||||||
| 		scheme.Scheme, | 		scheme.Scheme, | ||||||
| 		v1.EventSource{ | 		v1.EventSource{Component: component}, | ||||||
| 			Component: constants.OperatorName}) | 	) | ||||||
| 	return eventRecorder, nil | 	return eventRecorder, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,12 +1,19 @@ | ||||||
| package log | package log | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"sigs.k8s.io/controller-runtime/pkg/runtime/log" | 	"log" | ||||||
|  | 
 | ||||||
|  | 	"github.com/go-logr/logr" | ||||||
|  | 	"github.com/go-logr/zapr" | ||||||
|  | 	"go.uber.org/zap" | ||||||
| 	logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" | 	logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Log represents global logger
 | // Log represents global logger
 | ||||||
| var Log = log.Log.WithName("controller-jenkins") | var Log = logf.Log.WithName("controller-jenkins") | ||||||
|  | 
 | ||||||
|  | // Debug indicates that debug level is set
 | ||||||
|  | var Debug bool | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
| 	// VWarn defines warning log level
 | 	// VWarn defines warning log level
 | ||||||
|  | @ -15,8 +22,30 @@ const ( | ||||||
| 	VDebug = 1 | 	VDebug = 1 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // SetupLogger setups global logger
 | func zapLogger(debug bool) logr.Logger { | ||||||
| func SetupLogger(development *bool) { | 	var zapLog *zap.Logger | ||||||
| 	logf.SetLogger(logf.ZapLogger(*development)) | 	var err error | ||||||
| 	Log = log.Log.WithName("controller-jenkins") | 	zapLogCfg := zap.NewDevelopmentConfig() | ||||||
|  | 	if debug { | ||||||
|  | 		zapLogCfg.Level = zap.NewAtomicLevelAt(zap.DebugLevel) | ||||||
|  | 	} else { | ||||||
|  | 		zapLogCfg.Level = zap.NewAtomicLevelAt(zap.InfoLevel) | ||||||
|  | 	} | ||||||
|  | 	zapLog, err = zapLogCfg.Build(zap.AddStacktrace(zap.DPanicLevel), zap.AddCallerSkip(1)) | ||||||
|  | 	// who watches the watchmen?
 | ||||||
|  | 	fatalIfErr(err, log.Fatalf) | ||||||
|  | 	return zapr.NewLogger(zapLog) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func fatalIfErr(err error, f func(format string, v ...interface{})) { | ||||||
|  | 	if err != nil { | ||||||
|  | 		f("unable to construct the logger: %v", err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SetupLogger setups global logger
 | ||||||
|  | func SetupLogger(debug bool) { | ||||||
|  | 	Debug = debug | ||||||
|  | 	logf.SetLogger(zapLogger(debug)) | ||||||
|  | 	Log = logf.Log.WithName("controller-jenkins") | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue