github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/prow/cmd/horologium/main.go (about)

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"flag"
    21  	"fmt"
    22  	"time"
    23  
    24  	"github.com/sirupsen/logrus"
    25  
    26  	"k8s.io/test-infra/prow/config"
    27  	"k8s.io/test-infra/prow/cron"
    28  	"k8s.io/test-infra/prow/kube"
    29  	"k8s.io/test-infra/prow/logrusutil"
    30  	"k8s.io/test-infra/prow/pjutil"
    31  )
    32  
    33  type options struct {
    34  	configPath    string
    35  	jobConfigPath string
    36  }
    37  
    38  func gatherOptions() options {
    39  	o := options{}
    40  	flag.StringVar(&o.configPath, "config-path", "/etc/config/config.yaml", "Path to config.yaml.")
    41  	flag.StringVar(&o.jobConfigPath, "job-config-path", "", "Path to prow job configs.")
    42  	flag.Parse()
    43  	return o
    44  }
    45  
    46  func main() {
    47  	o := gatherOptions()
    48  	logrus.SetFormatter(
    49  		logrusutil.NewDefaultFieldsFormatter(nil, logrus.Fields{"component": "horologium"}),
    50  	)
    51  
    52  	configAgent := config.Agent{}
    53  	if err := configAgent.Start(o.configPath, o.jobConfigPath); err != nil {
    54  		logrus.WithError(err).Fatal("Error starting config agent.")
    55  	}
    56  
    57  	kc, err := kube.NewClientInCluster(configAgent.Config().ProwJobNamespace)
    58  	if err != nil {
    59  		logrus.WithError(err).Fatal("Error getting kube client.")
    60  	}
    61  
    62  	// start a cron
    63  	cr := cron.New()
    64  	cr.Start()
    65  
    66  	for now := range time.Tick(1 * time.Minute) {
    67  		start := time.Now()
    68  		if err := sync(kc, configAgent.Config(), cr, now); err != nil {
    69  			logrus.WithError(err).Error("Error syncing periodic jobs.")
    70  		}
    71  		logrus.Infof("Sync time: %v", time.Since(start))
    72  	}
    73  }
    74  
    75  type kubeClient interface {
    76  	ListProwJobs(string) ([]kube.ProwJob, error)
    77  	CreateProwJob(kube.ProwJob) (kube.ProwJob, error)
    78  }
    79  
    80  type cronClient interface {
    81  	SyncConfig(cfg *config.Config) error
    82  	QueuedJobs() []string
    83  }
    84  
    85  func sync(kc kubeClient, cfg *config.Config, cr cronClient, now time.Time) error {
    86  	jobs, err := kc.ListProwJobs(kube.EmptySelector)
    87  	if err != nil {
    88  		return fmt.Errorf("error listing prow jobs: %v", err)
    89  	}
    90  	latestJobs := pjutil.GetLatestProwJobs(jobs, kube.PeriodicJob)
    91  
    92  	// TODO(krzyzacy): retire the interval check, migrate everything to use cron
    93  	if err := cr.SyncConfig(cfg); err != nil {
    94  		logrus.WithError(err).Error("Error syncing cron jobs.")
    95  	}
    96  
    97  	cronTriggers := map[string]bool{}
    98  	for _, job := range cr.QueuedJobs() {
    99  		cronTriggers[job] = true
   100  	}
   101  
   102  	errs := []error{}
   103  	for _, p := range cfg.Periodics {
   104  		j, ok := latestJobs[p.Name]
   105  
   106  		if p.Cron == "" {
   107  			if !ok || (j.Complete() && now.Sub(j.Status.StartTime.Time) > p.GetInterval()) {
   108  				if _, err := kc.CreateProwJob(pjutil.NewProwJob(pjutil.PeriodicSpec(p), p.Labels)); err != nil {
   109  					errs = append(errs, err)
   110  				}
   111  			}
   112  		} else if _, exist := cronTriggers[p.Name]; exist {
   113  			if !ok || j.Complete() {
   114  				if _, err := kc.CreateProwJob(pjutil.NewProwJob(pjutil.PeriodicSpec(p), p.Labels)); err != nil {
   115  					errs = append(errs, err)
   116  				}
   117  			}
   118  		}
   119  	}
   120  
   121  	if len(errs) > 0 {
   122  		return fmt.Errorf("failed to create %d prowjobs: %v", len(errs), errs)
   123  	}
   124  
   125  	return nil
   126  }