2020-01-28 15:03:23 +09:00
/ *
Copyright 2020 The actions - runner - controller authors .
Licensed under the Apache License , Version 2.0 ( the "License" ) ;
you may not use this file except in compliance with the License .
You may obtain a copy of the License at
http : //www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing , software
distributed under the License is distributed on an "AS IS" BASIS ,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
See the License for the specific language governing permissions and
limitations under the License .
* /
package main
import (
"flag"
2020-02-01 20:18:16 +09:00
"fmt"
2020-01-28 15:03:23 +09:00
"os"
2021-02-18 20:19:08 +09:00
"strings"
2020-06-27 17:26:46 +09:00
"time"
2020-01-28 15:03:23 +09:00
2020-10-28 15:15:53 +02:00
"github.com/kelseyhightower/envconfig"
2020-01-28 15:03:23 +09:00
actionsv1alpha1 "github.com/summerwind/actions-runner-controller/api/v1alpha1"
"github.com/summerwind/actions-runner-controller/controllers"
2020-04-13 22:28:07 +09:00
"github.com/summerwind/actions-runner-controller/github"
2020-01-28 15:03:23 +09:00
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
// +kubebuilder:scaffold:imports
)
2020-02-03 16:56:52 +09:00
const (
2020-04-16 19:16:15 +09:00
defaultRunnerImage = "summerwind/actions-runner:latest"
defaultDockerImage = "docker:dind"
2020-02-03 16:56:52 +09:00
)
2020-01-28 15:03:23 +09:00
var (
scheme = runtime . NewScheme ( )
setupLog = ctrl . Log . WithName ( "setup" )
)
func init ( ) {
_ = clientgoscheme . AddToScheme ( scheme )
_ = actionsv1alpha1 . AddToScheme ( scheme )
// +kubebuilder:scaffold:scheme
}
func main ( ) {
2020-02-03 16:56:52 +09:00
var (
2020-04-13 22:28:07 +09:00
err error
ghClient * github . Client
2020-02-03 16:56:52 +09:00
metricsAddr string
enableLeaderElection bool
2020-06-27 17:26:46 +09:00
syncPeriod time . Duration
2020-02-03 16:56:52 +09:00
runnerImage string
dockerImage string
2021-02-18 20:19:08 +09:00
commonRunnerLabels commaSeparatedStringSlice
2020-02-03 16:56:52 +09:00
)
2020-10-28 15:15:53 +02:00
var c github . Config
err = envconfig . Process ( "github" , & c )
if err != nil {
fmt . Fprintln ( os . Stderr , "Error: Environment variable read failed." )
}
2020-01-28 15:03:23 +09:00
flag . StringVar ( & metricsAddr , "metrics-addr" , ":8080" , "The address the metric endpoint binds to." )
flag . BoolVar ( & enableLeaderElection , "enable-leader-election" , false ,
"Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager." )
2020-02-03 16:56:52 +09:00
flag . StringVar ( & runnerImage , "runner-image" , defaultRunnerImage , "The image name of self-hosted runner container." )
flag . StringVar ( & dockerImage , "docker-image" , defaultDockerImage , "The image name of docker sidecar container." )
2020-10-28 15:15:53 +02:00
flag . StringVar ( & c . Token , "github-token" , c . Token , "The personal access token of GitHub." )
flag . Int64Var ( & c . AppID , "github-app-id" , c . AppID , "The application ID of GitHub App." )
flag . Int64Var ( & c . AppInstallationID , "github-app-installation-id" , c . AppInstallationID , "The installation ID of GitHub App." )
flag . StringVar ( & c . AppPrivateKey , "github-app-private-key" , c . AppPrivateKey , "The path of a private key file to authenticate as a GitHub App" )
2020-06-27 17:26:46 +09:00
flag . DurationVar ( & syncPeriod , "sync-period" , 10 * time . Minute , "Determines the minimum frequency at which K8s resources managed by this controller are reconciled. When you use autoscaling, set to a lower value like 10 minute, because this corresponds to the minimum time to react on demand change" )
2021-02-18 20:19:08 +09:00
flag . Var ( & commonRunnerLabels , "common-runner-labels" , "Runner labels in the K1=V1,K2=V2,... format that are inherited all the runners created by the controller. See https://github.com/summerwind/actions-runner-controller/issues/321 for more information" )
2020-01-28 15:03:23 +09:00
flag . Parse ( )
2020-11-10 17:03:33 +09:00
logger := zap . New ( func ( o * zap . Options ) {
o . Development = true
} )
2020-10-28 15:15:53 +02:00
ghClient , err = c . NewClient ( )
if err != nil {
fmt . Fprintln ( os . Stderr , "Error: Client creation failed." , err )
2020-03-26 23:12:11 +09:00
os . Exit ( 1 )
}
2020-01-28 21:58:01 +09:00
2020-11-10 17:03:33 +09:00
ctrl . SetLogger ( logger )
2020-01-28 15:03:23 +09:00
mgr , err := ctrl . NewManager ( ctrl . GetConfigOrDie ( ) , ctrl . Options {
Scheme : scheme ,
MetricsBindAddress : metricsAddr ,
LeaderElection : enableLeaderElection ,
Port : 9443 ,
2020-06-27 17:26:46 +09:00
SyncPeriod : & syncPeriod ,
2020-01-28 15:03:23 +09:00
} )
if err != nil {
setupLog . Error ( err , "unable to start manager" )
os . Exit ( 1 )
}
2020-01-28 21:58:01 +09:00
runnerReconciler := & controllers . RunnerReconciler {
Client : mgr . GetClient ( ) ,
Log : ctrl . Log . WithName ( "controllers" ) . WithName ( "Runner" ) ,
Scheme : mgr . GetScheme ( ) ,
GitHubClient : ghClient ,
2020-02-03 16:56:52 +09:00
RunnerImage : runnerImage ,
DockerImage : dockerImage ,
2020-01-28 21:58:01 +09:00
}
if err = runnerReconciler . SetupWithManager ( mgr ) ; err != nil {
2020-01-28 15:03:23 +09:00
setupLog . Error ( err , "unable to create controller" , "controller" , "Runner" )
os . Exit ( 1 )
}
2020-02-21 03:01:52 +09:00
2020-03-10 09:14:11 +09:00
runnerSetReconciler := & controllers . RunnerReplicaSetReconciler {
2020-10-05 01:06:37 +01:00
Client : mgr . GetClient ( ) ,
Log : ctrl . Log . WithName ( "controllers" ) . WithName ( "RunnerReplicaSet" ) ,
Scheme : mgr . GetScheme ( ) ,
GitHubClient : ghClient ,
2020-02-21 03:01:52 +09:00
}
if err = runnerSetReconciler . SetupWithManager ( mgr ) ; err != nil {
2020-03-10 09:14:11 +09:00
setupLog . Error ( err , "unable to create controller" , "controller" , "RunnerReplicaSet" )
2020-02-21 03:01:52 +09:00
os . Exit ( 1 )
}
2020-02-26 21:23:23 +09:00
runnerDeploymentReconciler := & controllers . RunnerDeploymentReconciler {
2021-02-18 20:19:08 +09:00
Client : mgr . GetClient ( ) ,
Log : ctrl . Log . WithName ( "controllers" ) . WithName ( "RunnerDeployment" ) ,
Scheme : mgr . GetScheme ( ) ,
CommonRunnerLabels : commonRunnerLabels ,
2020-07-19 18:42:06 +09:00
}
if err = runnerDeploymentReconciler . SetupWithManager ( mgr ) ; err != nil {
setupLog . Error ( err , "unable to create controller" , "controller" , "RunnerDeployment" )
os . Exit ( 1 )
}
horizontalRunnerAutoscaler := & controllers . HorizontalRunnerAutoscalerReconciler {
2021-02-07 17:37:27 +09:00
Client : mgr . GetClient ( ) ,
Log : ctrl . Log . WithName ( "controllers" ) . WithName ( "HorizontalRunnerAutoscaler" ) ,
Scheme : mgr . GetScheme ( ) ,
GitHubClient : ghClient ,
CacheDuration : syncPeriod - 10 * time . Second ,
2020-02-26 21:23:23 +09:00
}
2020-07-19 18:42:06 +09:00
if err = horizontalRunnerAutoscaler . SetupWithManager ( mgr ) ; err != nil {
setupLog . Error ( err , "unable to create controller" , "controller" , "HorizontalRunnerAutoscaler" )
2020-02-26 21:23:23 +09:00
os . Exit ( 1 )
}
2020-04-30 22:11:59 +09:00
if err = ( & actionsv1alpha1 . Runner { } ) . SetupWebhookWithManager ( mgr ) ; err != nil {
setupLog . Error ( err , "unable to create webhook" , "webhook" , "Runner" )
os . Exit ( 1 )
}
if err = ( & actionsv1alpha1 . RunnerDeployment { } ) . SetupWebhookWithManager ( mgr ) ; err != nil {
setupLog . Error ( err , "unable to create webhook" , "webhook" , "RunnerDeployment" )
os . Exit ( 1 )
}
if err = ( & actionsv1alpha1 . RunnerReplicaSet { } ) . SetupWebhookWithManager ( mgr ) ; err != nil {
setupLog . Error ( err , "unable to create webhook" , "webhook" , "RunnerReplicaSet" )
os . Exit ( 1 )
}
2020-01-28 15:03:23 +09:00
// +kubebuilder:scaffold:builder
setupLog . Info ( "starting manager" )
if err := mgr . Start ( ctrl . SetupSignalHandler ( ) ) ; err != nil {
setupLog . Error ( err , "problem running manager" )
os . Exit ( 1 )
}
}
2021-02-18 20:19:08 +09:00
type commaSeparatedStringSlice [ ] string
func ( s * commaSeparatedStringSlice ) String ( ) string {
return fmt . Sprintf ( "%v" , * s )
}
func ( s * commaSeparatedStringSlice ) Set ( value string ) error {
for _ , v := range strings . Split ( value , "," ) {
if v == "" {
continue
}
* s = append ( * s , v )
}
return nil
}