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/controller/jenkins"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/event"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/log"
|
||||
"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/ready"
|
||||
sdkVersion "github.com/operator-framework/operator-sdk/version"
|
||||
"github.com/pkg/errors"
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/config"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
|
|
@ -37,31 +39,31 @@ func main() {
|
|||
debug := flag.Bool("debug", false, "Set log level to debug")
|
||||
flag.Parse()
|
||||
|
||||
log.SetupLogger(debug)
|
||||
log.SetupLogger(*debug)
|
||||
printInfo()
|
||||
|
||||
namespace, err := k8sutil.GetWatchNamespace()
|
||||
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))
|
||||
|
||||
// get a config to talk to the apiserver
|
||||
cfg, err := config.GetConfig()
|
||||
if err != nil {
|
||||
fatal(err, "failed to get config")
|
||||
fatal(errors.Wrap(err, "failed to get config"), *debug)
|
||||
}
|
||||
|
||||
// become the leader before proceeding
|
||||
err = leader.Become(context.TODO(), "jenkins-operator-lock")
|
||||
if err != nil {
|
||||
fatal(err, "failed to become leader")
|
||||
fatal(errors.Wrap(err, "failed to become leader"), *debug)
|
||||
}
|
||||
|
||||
r := ready.NewFileReady()
|
||||
err = r.Set()
|
||||
if err != nil {
|
||||
fatal(err, "failed to get ready.NewFileReady")
|
||||
fatal(errors.Wrap(err, "failed to get ready.NewFileReady"), *debug)
|
||||
}
|
||||
defer func() {
|
||||
_ = r.Unset()
|
||||
|
|
@ -70,36 +72,40 @@ func main() {
|
|||
// create a new Cmd to provide shared dependencies and start components
|
||||
mgr, err := manager.New(cfg, manager.Options{Namespace: namespace})
|
||||
if err != nil {
|
||||
fatal(err, "failed to create manager")
|
||||
fatal(errors.Wrap(err, "failed to create manager"), *debug)
|
||||
}
|
||||
|
||||
log.Log.Info("Registering Components.")
|
||||
|
||||
// setup Scheme for all resources
|
||||
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
|
||||
events, err := event.New(cfg)
|
||||
events, err := event.New(cfg, constants.OperatorName)
|
||||
if err != nil {
|
||||
fatal(err, "failed to create manager")
|
||||
fatal(errors.Wrap(err, "failed to create manager"), *debug)
|
||||
}
|
||||
|
||||
// setup Jenkins controller
|
||||
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.")
|
||||
|
||||
// start the Cmd
|
||||
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) {
|
||||
log.Log.Error(err, message)
|
||||
func fatal(err error, debug bool) {
|
||||
if debug {
|
||||
log.Log.Error(nil, fmt.Sprintf("%+v", err))
|
||||
} else {
|
||||
log.Log.Error(nil, fmt.Sprintf("%s", err))
|
||||
}
|
||||
os.Exit(-1)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,20 +64,13 @@ func (jenkins *jenkins) CreateOrUpdateJob(config, jobName string) (job *gojenkin
|
|||
if isNotFoundError(err) {
|
||||
job, err = jenkins.CreateJob(config, jobName)
|
||||
created = true
|
||||
return
|
||||
return job, true, errors.WithStack(err)
|
||||
} else if err != nil {
|
||||
return
|
||||
return job, false, errors.WithStack(err)
|
||||
}
|
||||
|
||||
err = job.UpdateConfig(config)
|
||||
return
|
||||
}
|
||||
|
||||
func isNotFoundError(err error) bool {
|
||||
if err != nil {
|
||||
return err.Error() == errorNotFound.Error()
|
||||
}
|
||||
return false
|
||||
return job, false, errors.WithStack(err)
|
||||
}
|
||||
|
||||
// BuildJenkinsAPIUrl returns Jenkins API URL
|
||||
|
|
@ -89,7 +82,7 @@ func BuildJenkinsAPIUrl(namespace, serviceName string, portNumber int, local, mi
|
|||
cmd.Stdout = &out
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
lines := strings.Split(out.String(), "\n")
|
||||
// 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
|
||||
}
|
||||
|
||||
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/go-logr/logr"
|
||||
stackerr "github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"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) {
|
||||
allPluginsInJenkins, err := jenkinsClient.GetPlugins(fetchAllPlugins)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, stackerr.WithStack(err)
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
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) {
|
||||
return err
|
||||
return stackerr.WithStack(err)
|
||||
}
|
||||
|
||||
if found.Data[resources.OperatorCredentialsSecretUserNameKey] != nil &&
|
||||
|
|
@ -210,7 +211,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createOperatorCredentialsSecret(meta
|
|||
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 {
|
||||
|
|
@ -218,7 +219,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createScriptsConfigMap(meta metav1.O
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r.createOrUpdateResource(configMap)
|
||||
return stackerr.WithStack(r.createOrUpdateResource(configMap))
|
||||
}
|
||||
|
||||
func (r *ReconcileJenkinsBaseConfiguration) createInitConfigurationConfigMap(meta metav1.ObjectMeta) error {
|
||||
|
|
@ -226,29 +227,26 @@ func (r *ReconcileJenkinsBaseConfiguration) createInitConfigurationConfigMap(met
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r.createOrUpdateResource(configMap)
|
||||
return stackerr.WithStack(r.createOrUpdateResource(configMap))
|
||||
}
|
||||
|
||||
func (r *ReconcileJenkinsBaseConfiguration) createBaseConfigurationConfigMap(meta metav1.ObjectMeta) error {
|
||||
configMap, err := resources.NewBaseConfigurationConfigMap(meta, r.jenkins)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r.createOrUpdateResource(configMap)
|
||||
configMap := resources.NewBaseConfigurationConfigMap(meta, r.jenkins)
|
||||
return stackerr.WithStack(r.createOrUpdateResource(configMap))
|
||||
}
|
||||
|
||||
func (r *ReconcileJenkinsBaseConfiguration) createUserConfigurationConfigMap(meta metav1.ObjectMeta) error {
|
||||
currentConfigMap := &corev1.ConfigMap{}
|
||||
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: resources.GetUserConfigurationConfigMapName(r.jenkins), Namespace: r.jenkins.Namespace}, currentConfigMap)
|
||||
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 {
|
||||
return err
|
||||
return stackerr.WithStack(err)
|
||||
}
|
||||
valid := r.verifyLabelsForWatchedResource(currentConfigMap)
|
||||
if !valid {
|
||||
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
|
||||
|
|
@ -258,19 +256,19 @@ func (r *ReconcileJenkinsBaseConfiguration) createRBAC(meta metav1.ObjectMeta) e
|
|||
serviceAccount := resources.NewServiceAccount(meta)
|
||||
err := r.createResource(serviceAccount)
|
||||
if err != nil && !errors.IsAlreadyExists(err) {
|
||||
return err
|
||||
return stackerr.WithStack(err)
|
||||
}
|
||||
|
||||
role := resources.NewRole(meta)
|
||||
err = r.createOrUpdateResource(role)
|
||||
if err != nil {
|
||||
return err
|
||||
return stackerr.WithStack(err)
|
||||
}
|
||||
|
||||
roleBinding := resources.NewRoleBinding(meta)
|
||||
err = r.createOrUpdateResource(roleBinding)
|
||||
if err != nil {
|
||||
return err
|
||||
return stackerr.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -279,7 +277,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createRBAC(meta metav1.ObjectMeta) e
|
|||
func (r *ReconcileJenkinsBaseConfiguration) createService(meta metav1.ObjectMeta) error {
|
||||
err := r.createResource(resources.NewService(meta, r.minikube))
|
||||
if err != nil && !apierrors.IsAlreadyExists(err) {
|
||||
return err
|
||||
return stackerr.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -290,7 +288,7 @@ func (r *ReconcileJenkinsBaseConfiguration) getJenkinsMasterPod(meta metav1.Obje
|
|||
currentJenkinsMasterPod := &corev1.Pod{}
|
||||
err := r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: jenkinsMasterPod.Name, Namespace: jenkinsMasterPod.Namespace}, currentJenkinsMasterPod)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, err // don't wrap error
|
||||
}
|
||||
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))
|
||||
err = r.createResource(jenkinsMasterPod)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
return reconcile.Result{}, stackerr.WithStack(err)
|
||||
}
|
||||
r.jenkins.Status = v1alpha1.JenkinsStatus{}
|
||||
err = r.updateResource(r.jenkins)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
return reconcile.Result{}, err // don't wrap error
|
||||
}
|
||||
return reconcile.Result{}, nil
|
||||
} else if err != nil && !errors.IsNotFound(err) {
|
||||
return reconcile.Result{}, err
|
||||
return reconcile.Result{}, stackerr.WithStack(err)
|
||||
}
|
||||
|
||||
// Recreate pod
|
||||
|
|
@ -357,7 +355,7 @@ func (r *ReconcileJenkinsBaseConfiguration) restartJenkinsMasterPod(meta metav1.
|
|||
if err != nil {
|
||||
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) {
|
||||
|
|
@ -397,7 +395,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient(meta metav1.Obje
|
|||
credentialsSecret := &corev1.Secret{}
|
||||
err = r.k8sClient.Get(context.TODO(), types.NamespacedName{Name: resources.GetOperatorCredentialsSecretName(r.jenkins), Namespace: r.jenkins.ObjectMeta.Namespace}, credentialsSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, stackerr.WithStack(err)
|
||||
}
|
||||
currentJenkinsMasterPod, err := r.getJenkinsMasterPod(meta)
|
||||
if err != nil {
|
||||
|
|
@ -437,7 +435,7 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureJenkinsClient(meta metav1.Obje
|
|||
credentialsSecret.Data[resources.OperatorCredentialsSecretTokenCreationKey] = now
|
||||
err = r.updateResource(credentialsSecret)
|
||||
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)}
|
||||
err = r.k8sClient.Get(context.TODO(), namespaceName, configuration)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
return reconcile.Result{}, stackerr.WithStack(err)
|
||||
}
|
||||
|
||||
done, err := groovyClient.EnsureGroovyJob(configuration.Data, r.jenkins)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ package base
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
stackerr "github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
|
@ -13,33 +13,33 @@ import (
|
|||
func (r *ReconcileJenkinsBaseConfiguration) createResource(obj metav1.Object) error {
|
||||
runtimeObj, ok := obj.(runtime.Object)
|
||||
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
|
||||
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 {
|
||||
runtimeObj, ok := obj.(runtime.Object)
|
||||
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)
|
||||
_ = 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 {
|
||||
runtimeObj, ok := obj.(runtime.Object)
|
||||
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)
|
||||
|
|
@ -49,7 +49,7 @@ func (r *ReconcileJenkinsBaseConfiguration) createOrUpdateResource(obj metav1.Ob
|
|||
if err != nil && errors.IsAlreadyExists(err) {
|
||||
return r.updateResource(obj)
|
||||
} else if err != nil && !errors.IsAlreadyExists(err) {
|
||||
return err
|
||||
return stackerr.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ func GetBaseConfigurationConfigMapName(jenkins *v1alpha1.Jenkins) string {
|
|||
}
|
||||
|
||||
// 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)
|
||||
|
||||
return &corev1.ConfigMap{
|
||||
|
|
@ -183,5 +183,5 @@ func NewBaseConfigurationConfigMap(meta metav1.ObjectMeta, jenkins *v1alpha1.Jen
|
|||
jenkins.ObjectMeta.Namespace, GetResourceName(jenkins), HTTPPortInt),
|
||||
"7-configure-views.groovy": configureViews,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,15 @@ package resources
|
|||
import (
|
||||
"bytes"
|
||||
"text/template"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// render executes a parsed template (go-template) with configuration from data
|
||||
func render(template *template.Template, data interface{}) (string, error) {
|
||||
var buffer bytes.Buffer
|
||||
if err := template.Execute(&buffer, data); err != nil {
|
||||
return "", err
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
return buffer.String(), nil
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/jobs"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
k8s "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
|
@ -73,7 +74,7 @@ func (r *ReconcileUserConfiguration) ensureSeedJobs() (reconcile.Result, error)
|
|||
return reconcile.Result{}, nil
|
||||
}
|
||||
// unexpected error - requeue reconciliation loop
|
||||
return reconcile.Result{}, err
|
||||
return reconcile.Result{}, errors.WithStack(err)
|
||||
}
|
||||
// build not finished yet - requeue reconciliation loop with timeout
|
||||
if !done {
|
||||
|
|
@ -94,7 +95,7 @@ func (r *ReconcileUserConfiguration) ensureUserConfiguration(jenkinsClient jenki
|
|||
namespaceName := types.NamespacedName{Namespace: r.jenkins.Namespace, Name: resources.GetUserConfigurationConfigMapName(r.jenkins)}
|
||||
err = r.k8sClient.Get(context.TODO(), namespaceName, configuration)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
return reconcile.Result{}, errors.WithStack(err)
|
||||
}
|
||||
|
||||
done, err := groovyClient.EnsureGroovyJob(configuration.Data, r.jenkins)
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ import (
|
|||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkinsio/v1alpha1"
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/log"
|
||||
|
||||
stackerr "github.com/pkg/errors"
|
||||
"k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
|
@ -55,7 +55,7 @@ func (r *ReconcileUserConfiguration) validateSeedJobs(jenkins *v1alpha1.Jenkins)
|
|||
logger.Info("secret not found")
|
||||
valid = false
|
||||
} else if err != nil {
|
||||
return false, err
|
||||
return false, stackerr.WithStack(err)
|
||||
}
|
||||
|
||||
privateKey := string(deployKeySecret.Data[seedJob.PrivateKey.SecretKeyRef.Key])
|
||||
|
|
@ -77,17 +77,17 @@ func (r *ReconcileUserConfiguration) validateSeedJobs(jenkins *v1alpha1.Jenkins)
|
|||
func validatePrivateKey(privateKey string) error {
|
||||
block, _ := pem.Decode([]byte(privateKey))
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
return stackerr.WithStack(err)
|
||||
}
|
||||
|
||||
err = priv.Validate()
|
||||
if err != nil {
|
||||
return err
|
||||
return stackerr.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
"github.com/jenkinsci/kubernetes-operator/pkg/log"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
|
|
@ -57,13 +58,13 @@ func add(mgr manager.Manager, r reconcile.Reconciler) error {
|
|||
// Create a new controller
|
||||
c, err := controller.New("jenkins-controller", mgr, controller.Options{Reconciler: r})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// Watch for changes to primary resource Jenkins
|
||||
err = c.Watch(&source.Kind{Type: &v1alpha1.Jenkins{}}, &handler.EnqueueRequestForObject{})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// 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{},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
jenkinsHandler := &enqueueRequestForJenkins{}
|
||||
err = c.Watch(&source.Kind{Type: &corev1.Secret{}}, jenkinsHandler)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
err = c.Watch(&source.Kind{Type: &corev1.ConfigMap{}}, jenkinsHandler)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
@ -109,7 +110,11 @@ func (r *ReconcileJenkins) Reconcile(request reconcile.Request) (reconcile.Resul
|
|||
logger.V(log.VWarn).Info(err.Error())
|
||||
return reconcile.Result{Requeue: true}, nil
|
||||
} else if err != nil {
|
||||
logger.V(log.VWarn).Info(fmt.Sprintf("Reconcile loop failed: %+v", err))
|
||||
if log.Debug {
|
||||
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 result, nil
|
||||
|
|
@ -127,7 +132,7 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg
|
|||
return reconcile.Result{}, nil
|
||||
}
|
||||
// Error reading the object - requeue the request.
|
||||
return reconcile.Result{}, err
|
||||
return reconcile.Result{}, errors.WithStack(err)
|
||||
}
|
||||
|
||||
err = r.setDefaults(jenkins, logger)
|
||||
|
|
@ -161,7 +166,7 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg
|
|||
jenkins.Status.BaseConfigurationCompletedTime = &now
|
||||
err = r.client.Update(context.TODO(), jenkins)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
return reconcile.Result{}, errors.WithStack(err)
|
||||
}
|
||||
logger.Info("Base configuration phase is complete")
|
||||
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
|
||||
err = r.client.Update(context.TODO(), jenkins)
|
||||
if err != nil {
|
||||
return reconcile.Result{}, err
|
||||
return reconcile.Result{}, errors.WithStack(err)
|
||||
}
|
||||
logger.Info("User configuration phase is complete")
|
||||
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 {
|
||||
return r.client.Update(context.TODO(), jenkins)
|
||||
return errors.WithStack(r.client.Update(context.TODO(), jenkins))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package jobs
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
|
@ -11,21 +10,22 @@ import (
|
|||
"github.com/jenkinsci/kubernetes-operator/pkg/log"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
k8s "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
var (
|
||||
// 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 = errors.New("build failed")
|
||||
ErrorBuildFailed = fmt.Errorf("build failed")
|
||||
// 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 = 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 = errors.New("404")
|
||||
ErrorNotFound = fmt.Errorf("404")
|
||||
// BuildRetires - determines max amount of retires for failed build
|
||||
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) {
|
||||
jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Ensuring build, name:'%s' hash:'%s'", jobName, hash))
|
||||
|
||||
build, err := jobs.getBuildFromStatus(jobName, hash, jenkins)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
build := jobs.getBuildFromStatus(jobName, hash, jenkins)
|
||||
if build != nil {
|
||||
jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Build exists in status, %+v", build))
|
||||
switch build.Status {
|
||||
|
|
@ -86,16 +82,16 @@ func (jobs *Jobs) EnsureBuildJob(jobName, hash string, parameters map[string]str
|
|||
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 {
|
||||
builds := jenkins.Status.Builds
|
||||
for _, build := range builds {
|
||||
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) {
|
||||
|
|
@ -103,7 +99,6 @@ func (jobs *Jobs) ensureSuccessBuild(build v1alpha1.Build, jenkins *v1alpha1.Jen
|
|||
|
||||
if !preserveStatus {
|
||||
err := jobs.removeBuildFromStatus(build, jenkins)
|
||||
jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Removing build from status, %+v", build))
|
||||
if err != nil {
|
||||
jobs.logger.V(log.VWarn).Info(fmt.Sprintf("Couldn't remove build from status, %+v", build))
|
||||
return false, err
|
||||
|
|
@ -122,7 +117,7 @@ func (jobs *Jobs) ensureRunningBuild(build v1alpha1.Build, jenkins *v1alpha1.Jen
|
|||
return false, nil
|
||||
} else if err != nil {
|
||||
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() != "" {
|
||||
|
|
@ -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))
|
||||
|
||||
if !preserveStatus {
|
||||
jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Removing build from status, %+v", build))
|
||||
err := jobs.removeBuildFromStatus(build, jenkins)
|
||||
if err != nil {
|
||||
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)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, errors.WithStack(err)
|
||||
}
|
||||
|
||||
_, err = jenkinsBuild.Stop()
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, errors.WithStack(err)
|
||||
}
|
||||
|
||||
jenkinsBuild, err = jobs.jenkinsClient.GetBuild(build.JobName, build.Number)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, errors.WithStack(err)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
if !preserveStatus {
|
||||
jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Removing build from status, %+v", build))
|
||||
err = jobs.removeBuildFromStatus(build, jenkins)
|
||||
if err != nil {
|
||||
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 {
|
||||
jobs.logger.V(log.VDebug).Info(fmt.Sprintf("Removing build from status, %+v", build))
|
||||
builds := make([]v1alpha1.Build, len(jenkins.Status.Builds))
|
||||
for _, existingBuild := range jenkins.Status.Builds {
|
||||
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
|
||||
err := jobs.k8sClient.Update(context.TODO(), jenkins)
|
||||
if err != nil {
|
||||
return err
|
||||
return err // don't wrap because apierrors.IsConflict(err) won't work in jenkins_controller
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
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
|
||||
|
||||
|
|
@ -246,7 +240,7 @@ func (jobs *Jobs) buildJob(build v1alpha1.Build, parameters map[string]string, j
|
|||
_, err = jobs.jenkinsClient.BuildJob(build.JobName, parameters)
|
||||
if err != nil {
|
||||
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
|
||||
|
|
@ -281,7 +275,7 @@ func (jobs *Jobs) updateBuildStatus(build v1alpha1.Build, jenkins *v1alpha1.Jenk
|
|||
}
|
||||
err := jobs.k8sClient.Update(context.TODO(), jenkins)
|
||||
if err != nil {
|
||||
return err
|
||||
return err // don't wrap because apierrors.IsConflict(err) won't work in jenkins_controller
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/log"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Plugin represents jenkins plugin
|
||||
|
|
@ -22,7 +24,7 @@ func (p Plugin) String() string {
|
|||
func New(nameWithVersion string) (*Plugin, error) {
|
||||
val := strings.SplitN(nameWithVersion, ":", 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{
|
||||
Name: val[0],
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ import (
|
|||
)
|
||||
|
||||
func TestVerifyDependencies(t *testing.T) {
|
||||
debug := false
|
||||
log.SetupLogger(&debug)
|
||||
log.SetupLogger(false)
|
||||
|
||||
t.Run("happy, single root plugin with one dependent plugin", func(t *testing.T) {
|
||||
basePlugins := map[Plugin][]Plugin{
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ package event
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/constants"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
|
@ -38,8 +37,8 @@ type recorder struct {
|
|||
}
|
||||
|
||||
// New returns recorder used to emit events
|
||||
func New(config *rest.Config) (Recorder, error) {
|
||||
eventRecorder, err := initializeEventRecorder(config)
|
||||
func New(config *rest.Config, component string) (Recorder, error) {
|
||||
eventRecorder, err := initializeEventRecorder(config, component)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -49,10 +48,10 @@ func New(config *rest.Config) (Recorder, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func initializeEventRecorder(config *rest.Config) (record.EventRecorder, error) {
|
||||
func initializeEventRecorder(config *rest.Config, component string) (record.EventRecorder, error) {
|
||||
client, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.WithStack(err)
|
||||
}
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
//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("")})
|
||||
eventRecorder := eventBroadcaster.NewRecorder(
|
||||
scheme.Scheme,
|
||||
v1.EventSource{
|
||||
Component: constants.OperatorName})
|
||||
v1.EventSource{Component: component},
|
||||
)
|
||||
return eventRecorder, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,19 @@
|
|||
package log
|
||||
|
||||
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"
|
||||
)
|
||||
|
||||
// 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 (
|
||||
// VWarn defines warning log level
|
||||
|
|
@ -15,8 +22,30 @@ const (
|
|||
VDebug = 1
|
||||
)
|
||||
|
||||
// SetupLogger setups global logger
|
||||
func SetupLogger(development *bool) {
|
||||
logf.SetLogger(logf.ZapLogger(*development))
|
||||
Log = log.Log.WithName("controller-jenkins")
|
||||
func zapLogger(debug bool) logr.Logger {
|
||||
var zapLog *zap.Logger
|
||||
var err error
|
||||
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