@@ -20,9 +20,7 @@ import (
2020 "fmt"
2121 "os"
2222 "path/filepath"
23- "strconv"
2423 "strings"
25- "time"
2624
2725 // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
2826 // to ensure that exec-entrypoint and run can make use of them.
@@ -34,7 +32,6 @@ import (
3432 ctrl "sigs.k8s.io/controller-runtime"
3533 "sigs.k8s.io/controller-runtime/pkg/certwatcher"
3634 "sigs.k8s.io/controller-runtime/pkg/healthz"
37- "sigs.k8s.io/controller-runtime/pkg/log/zap"
3835 "sigs.k8s.io/controller-runtime/pkg/metrics/filters"
3936 metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
4037 "sigs.k8s.io/controller-runtime/pkg/webhook"
@@ -53,58 +50,6 @@ const (
5350 defaultPoolConcurrency = 16
5451)
5552
56- type ConcurrencyConfig map [string ]int
57-
58- func (c * ConcurrencyConfig ) String () string {
59- if * c == nil {
60- return ""
61- }
62- parts := make ([]string , 0 , len (* c ))
63- for k , v := range * c {
64- parts = append (parts , fmt .Sprintf ("%s=%d" , k , v ))
65- }
66- return strings .Join (parts , ";" )
67- }
68-
69- func (c * ConcurrencyConfig ) Set (value string ) error {
70- if * c == nil {
71- * c = make (ConcurrencyConfig )
72- }
73- if value == "" {
74- return nil
75- }
76- pairs := strings .Split (value , ";" )
77- for _ , pair := range pairs {
78- pair = strings .TrimSpace (pair )
79- if pair == "" {
80- continue
81- }
82- kv := strings .SplitN (pair , "=" , 2 )
83- if len (kv ) != 2 {
84- return fmt .Errorf ("invalid concurrency config format: %s, expected format: controller=value" , pair )
85- }
86- name := strings .TrimSpace (kv [0 ])
87- val , err := strconv .Atoi (strings .TrimSpace (kv [1 ]))
88- if err != nil {
89- return fmt .Errorf ("invalid concurrency value for %s: %v" , name , err )
90- }
91- if val <= 0 {
92- return fmt .Errorf ("concurrency value must be positive for %s: %d" , name , val )
93- }
94- (* c )[name ] = val
95- }
96- return nil
97- }
98-
99- func (c * ConcurrencyConfig ) Get (name string , defaultVal int ) int {
100- if * c != nil {
101- if v , ok := (* c )[name ]; ok {
102- return v
103- }
104- }
105- return defaultVal
106- }
107-
10853var (
10954 scheme = runtime .NewScheme ()
11055 setupLog = ctrl .Log .WithName ("setup" )
@@ -132,107 +77,30 @@ func init() {
13277
13378// nolint:gocyclo
13479func main () {
135- var metricsAddr string
136- var metricsCertPath , metricsCertName , metricsCertKey string
137- var webhookCertPath , webhookCertName , webhookCertKey string
138- var enableLeaderElection bool
139- var probeAddr string
140- var secureMetrics bool
141- var enableHTTP2 bool
142- var allowWeakTLSKeyLengths bool
14380 var tlsOpts []func (* tls.Config )
14481
145- // Log file options
146- var enableFileLog bool
147- var logFilePath string
148- var logMaxSize int
149- var logMaxBackups int
150- var logMaxAge int
151- var logCompress bool
152-
153- // Kubernetes client rate limiter options
154- var kubeClientQPS float64
155- var kubeClientBurst int
156-
157- // Controller concurrency options
158- var concurrencyConfig ConcurrencyConfig
159-
160- flag .StringVar (& metricsAddr , "metrics-bind-address" , "0" , "The address the metrics endpoint binds to. " +
161- "Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service." )
162- flag .StringVar (& probeAddr , "health-probe-bind-address" , ":8081" , "The address the probe endpoint binds to." )
163- flag .BoolVar (& enableLeaderElection , "leader-elect" , false ,
164- "Enable leader election for controller manager. " +
165- "Enabling this will ensure there is only one active controller manager." )
166- flag .BoolVar (& secureMetrics , "metrics-secure" , true ,
167- "If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead." )
168- flag .StringVar (& webhookCertPath , "webhook-cert-path" , "" , "The directory that contains the webhook certificate." )
169- flag .StringVar (& webhookCertName , "webhook-cert-name" , "tls.crt" , "The name of the webhook certificate file." )
170- flag .StringVar (& webhookCertKey , "webhook-cert-key" , "tls.key" , "The name of the webhook key file." )
171- flag .StringVar (& metricsCertPath , "metrics-cert-path" , "" ,
172- "The directory that contains the metrics server certificate." )
173- flag .StringVar (& metricsCertName , "metrics-cert-name" , "tls.crt" , "The name of the metrics server certificate file." )
174- flag .StringVar (& metricsCertKey , "metrics-cert-key" , "tls.key" , "The name of the metrics server key file." )
175- flag .BoolVar (& enableHTTP2 , "enable-http2" , false ,
176- "If set, HTTP/2 will be enabled for the metrics and webhook servers" )
177- flag .BoolVar (
178- & allowWeakTLSKeyLengths ,
179- "allow-weak-tls-keylengths" ,
180- false ,
181- "If set, allows TLS certificates below NIST 2030 minimum key/hash lengths (not recommended)." ,
182- )
183-
184- // Log file flags
185- flag .BoolVar (& enableFileLog , "enable-file-log" , false , "Enable log output to file" )
186- flag .StringVar (& logFilePath , "log-file-path" , "/var/log/sandbox-controller/controller.log" , "Path to the log file" )
187- flag .IntVar (& logMaxSize , "log-max-size" , 100 , "Maximum size in megabytes of the log file before it gets rotated" )
188- flag .IntVar (& logMaxBackups , "log-max-backups" , 10 , "Maximum number of old log files to retain" )
189- flag .IntVar (& logMaxAge , "log-max-age" , 30 , "Maximum number of days to retain old log files" )
190- flag .BoolVar (& logCompress , "log-compress" , true , "Compress determines if the rotated log files should be compressed using gzip" )
191- flag .Float64Var (& kubeClientQPS , "kube-client-qps" , 100 , "QPS for Kubernetes client rate limiter." )
192- flag .IntVar (& kubeClientBurst , "kube-client-burst" , 200 , "Burst for Kubernetes client rate limiter." )
193- flag .Var (& concurrencyConfig , "concurrency" , "Controller concurrency settings in format: controller1=N;controller2=M. " +
194- "Available controllers: batchsandbox, pool. " +
195- "Example: --concurrency='batchsandbox=32;pool=128'" )
196-
197- // Image committer
198- var imageCommitterImage string
199- flag .StringVar (& imageCommitterImage , "image-committer-image" , "image-committer:dev" , "The image used for commit operations (contains nerdctl tool)." )
200-
201- // Commit job timeout
202- var commitJobTimeout time.Duration
203- flag .DurationVar (& commitJobTimeout , "commit-job-timeout" , 10 * time .Minute , "The timeout duration for commit jobs." )
204-
205- var snapshotRegistry string
206- flag .StringVar (& snapshotRegistry , "snapshot-registry" , "" , "OCI registry for snapshot images (e.g., registry.example.com/snapshots)." )
207-
208- var snapshotRegistryInsecure bool
209- flag .BoolVar (& snapshotRegistryInsecure , "snapshot-registry-insecure" , false , "Use insecure registry mode when pushing snapshot images." )
210-
211- var snapshotPushSecret string
212- flag .StringVar (& snapshotPushSecret , "snapshot-push-secret" , "" , "K8s Secret name for pushing snapshots to registry." )
213-
214- var resumePullSecret string
215- flag .StringVar (& resumePullSecret , "resume-pull-secret" , "" , "K8s Secret name for pulling snapshot images during resume." )
216-
217- opts := zap.Options {}
218- opts .BindFlags (flag .CommandLine )
82+ options := & controllerOptions {}
83+ options .bindFlags (flag .CommandLine )
21984
22085 flag .Parse ()
22186
22287 // Setup logger with file rotation support
22388 logOpts := logging.Options {
224- Development : opts .Development ,
225- EnableFileOutput : enableFileLog ,
226- LogFilePath : logFilePath ,
227- MaxSize : logMaxSize ,
228- MaxBackups : logMaxBackups ,
229- MaxAge : logMaxAge ,
230- Compress : logCompress ,
231- ZapOptions : opts ,
89+ Development : options . zapOptions .Development ,
90+ EnableFileOutput : options . enableFileLog ,
91+ LogFilePath : options . logFilePath ,
92+ MaxSize : options . logMaxSize ,
93+ MaxBackups : options . logMaxBackups ,
94+ MaxAge : options . logMaxAge ,
95+ Compress : options . logCompress ,
96+ ZapOptions : options . zapOptions ,
23297 }
23398
23499 logger := logging .NewLoggerWithZapOptions (logOpts )
235100 ctrl .SetLogger (logger )
101+ if options .legacyKlogVerbosity != "" {
102+ setupLog .Info ("deprecated --v flag ignored; use --zap-log-level instead" , "v" , options .legacyKlogVerbosity )
103+ }
236104
237105 // if the enable-http2 flag is false (the default), http/2 should be disabled
238106 // due to its vulnerabilities. More specifically, disabling http/2 will
@@ -249,7 +117,7 @@ func main() {
249117 c .MinVersion = tls .VersionTLS12
250118 })
251119
252- if ! enableHTTP2 {
120+ if ! options . enableHTTP2 {
253121 tlsOpts = append (tlsOpts , disableHTTP2 )
254122 }
255123
@@ -259,10 +127,10 @@ func main() {
259127 // Initial webhook TLS options
260128 webhookTLSOpts := tlsOpts
261129
262- if len (webhookCertPath ) > 0 {
263- webhookCertFile := filepath .Join (webhookCertPath , webhookCertName )
264- webhookKeyFile := filepath .Join (webhookCertPath , webhookCertKey )
265- if ! allowWeakTLSKeyLengths {
130+ if len (options . webhookCertPath ) > 0 {
131+ webhookCertFile := filepath .Join (options . webhookCertPath , options . webhookCertName )
132+ webhookKeyFile := filepath .Join (options . webhookCertPath , options . webhookCertKey )
133+ if ! options . allowWeakTLSKeyLengths {
266134 if err := cryptoutil .ValidateCertificateKeyPair (webhookCertFile , webhookKeyFile ); err != nil {
267135 setupLog .Error (err , "Webhook certificate does not meet NIST minimum key/hash requirements" ,
268136 "webhook-cert-file" , webhookCertFile , "webhook-key-file" , webhookKeyFile )
@@ -271,7 +139,7 @@ func main() {
271139 }
272140
273141 setupLog .Info ("Initializing webhook certificate watcher using provided certificates" ,
274- "webhook-cert-path" , webhookCertPath , "webhook-cert-name" , webhookCertName , "webhook-cert-key" , webhookCertKey )
142+ "webhook-cert-path" , options . webhookCertPath , "webhook-cert-name" , options . webhookCertName , "webhook-cert-key" , options . webhookCertKey )
275143
276144 var err error
277145 webhookCertWatcher , err = certwatcher .New (
@@ -289,7 +157,7 @@ func main() {
289157 if err != nil {
290158 return nil , err
291159 }
292- if allowWeakTLSKeyLengths {
160+ if options . allowWeakTLSKeyLengths {
293161 return cert , nil
294162 }
295163 if err := cryptoutil .ValidateTLSCertificate (webhookCertFile , cert ); err != nil {
@@ -309,12 +177,12 @@ func main() {
309177 // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.21.0/pkg/metrics/server
310178 // - https://book.kubebuilder.io/reference/metrics.html
311179 metricsServerOptions := metricsserver.Options {
312- BindAddress : metricsAddr ,
313- SecureServing : secureMetrics ,
180+ BindAddress : options . metricsAddr ,
181+ SecureServing : options . secureMetrics ,
314182 TLSOpts : tlsOpts ,
315183 }
316184
317- if secureMetrics {
185+ if options . secureMetrics {
318186 // FilterProvider is used to protect the metrics endpoint with authn/authz.
319187 // These configurations ensure that only authorized users and service accounts
320188 // can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info:
@@ -330,10 +198,10 @@ func main() {
330198 // - [METRICS-WITH-CERTS] at config/default/kustomization.yaml to generate and use certificates
331199 // managed by cert-manager for the metrics server.
332200 // - [PROMETHEUS-WITH-CERTS] at config/prometheus/kustomization.yaml for TLS certification.
333- if len (metricsCertPath ) > 0 {
334- metricsCertFile := filepath .Join (metricsCertPath , metricsCertName )
335- metricsKeyFile := filepath .Join (metricsCertPath , metricsCertKey )
336- if ! allowWeakTLSKeyLengths && metricsAddr != "0" && secureMetrics {
201+ if len (options . metricsCertPath ) > 0 {
202+ metricsCertFile := filepath .Join (options . metricsCertPath , options . metricsCertName )
203+ metricsKeyFile := filepath .Join (options . metricsCertPath , options . metricsCertKey )
204+ if ! options . allowWeakTLSKeyLengths && options . metricsAddr != "0" && options . secureMetrics {
337205 if err := cryptoutil .ValidateCertificateKeyPair (metricsCertFile , metricsKeyFile ); err != nil {
338206 setupLog .Error (err , "Metrics certificate does not meet NIST minimum key/hash requirements" ,
339207 "metrics-cert-file" , metricsCertFile , "metrics-key-file" , metricsKeyFile )
@@ -342,7 +210,7 @@ func main() {
342210 }
343211
344212 setupLog .Info ("Initializing metrics certificate watcher using provided certificates" ,
345- "metrics-cert-path" , metricsCertPath , "metrics-cert-name" , metricsCertName , "metrics-cert-key" , metricsCertKey )
213+ "metrics-cert-path" , options . metricsCertPath , "metrics-cert-name" , options . metricsCertName , "metrics-cert-key" , options . metricsCertKey )
346214
347215 var err error
348216 metricsCertWatcher , err = certwatcher .New (
@@ -360,7 +228,7 @@ func main() {
360228 if err != nil {
361229 return nil , err
362230 }
363- if allowWeakTLSKeyLengths {
231+ if options . allowWeakTLSKeyLengths {
364232 return cert , nil
365233 }
366234 if err := cryptoutil .ValidateTLSCertificate (metricsCertFile , cert ); err != nil {
@@ -373,19 +241,19 @@ func main() {
373241
374242 config := ctrl .GetConfigOrDie ()
375243 // Set client rate limiter if specified
376- if kubeClientQPS > 0 {
377- config .QPS = float32 (kubeClientQPS )
244+ if options . kubeClientQPS > 0 {
245+ config .QPS = float32 (options . kubeClientQPS )
378246 }
379- if kubeClientBurst > 0 {
380- config .Burst = kubeClientBurst
247+ if options . kubeClientBurst > 0 {
248+ config .Burst = options . kubeClientBurst
381249 }
382250
383251 mgr , err := ctrl .NewManager (config , ctrl.Options {
384252 Scheme : scheme ,
385253 Metrics : metricsServerOptions ,
386254 WebhookServer : webhookServer ,
387- HealthProbeBindAddress : probeAddr ,
388- LeaderElection : enableLeaderElection ,
255+ HealthProbeBindAddress : options . probeAddr ,
256+ LeaderElection : options . enableLeaderElection ,
389257 LeaderElectionID : "2fa1c467.opensandbox.io" ,
390258 // LeaderElectionReleaseOnCancel causes the leader to voluntarily release the lease
391259 // when the Manager is stopped, allowing a new leader to acquire it without waiting
@@ -407,8 +275,8 @@ func main() {
407275 batchSandboxKindName = strings .ToLower (getKindFromType (& sandboxv1alpha1.BatchSandbox {}))
408276 poolKindName = strings .ToLower (getKindFromType (& sandboxv1alpha1.Pool {}))
409277 )
410- batchSandboxConcurrency := concurrencyConfig .Get (batchSandboxKindName , defaultBatchSandboxConcurrency )
411- poolConcurrency := concurrencyConfig .Get (poolKindName , defaultPoolConcurrency )
278+ batchSandboxConcurrency := options . concurrencyConfig .Get (batchSandboxKindName , defaultBatchSandboxConcurrency )
279+ poolConcurrency := options . concurrencyConfig .Get (poolKindName , defaultPoolConcurrency )
412280 setupLog .Info ("controller concurrency configured" , batchSandboxKindName , batchSandboxConcurrency , poolKindName , poolConcurrency )
413281
414282 profileStore := poolassign .NewProfileStore ()
@@ -422,7 +290,7 @@ func main() {
422290 Client : mgr .GetClient (),
423291 Scheme : mgr .GetScheme (),
424292 Recorder : mgr .GetEventRecorderFor ("batchsandbox-controller" ),
425- ResumePullSecret : resumePullSecret ,
293+ ResumePullSecret : options . resumePullSecret ,
426294 ProfileStore : profileStore ,
427295 }).SetupWithManager (mgr , batchSandboxConcurrency ); err != nil {
428296 setupLog .Error (err , "unable to create controller" , "controller" , "BatchSandbox" )
@@ -442,11 +310,11 @@ func main() {
442310 Client : mgr .GetClient (),
443311 Scheme : mgr .GetScheme (),
444312 Recorder : mgr .GetEventRecorderFor ("sandboxsnapshot-controller" ),
445- ImageCommitterImage : imageCommitterImage ,
446- CommitJobTimeout : commitJobTimeout ,
447- SnapshotRegistry : snapshotRegistry ,
448- SnapshotRegistryInsecure : snapshotRegistryInsecure ,
449- SnapshotPushSecret : snapshotPushSecret ,
313+ ImageCommitterImage : options . imageCommitterImage ,
314+ CommitJobTimeout : options . commitJobTimeout ,
315+ SnapshotRegistry : options . snapshotRegistry ,
316+ SnapshotRegistryInsecure : options . snapshotRegistryInsecure ,
317+ SnapshotPushSecret : options . snapshotPushSecret ,
450318 }).SetupWithManager (mgr ); err != nil {
451319 setupLog .Error (err , "unable to create controller" , "controller" , "SandboxSnapshot" )
452320 os .Exit (1 )
0 commit comments