k8s.io/registry.k8s.io@v0.3.1/cmd/archeio/main.go (about)

     1  /*
     2  Copyright 2022 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  	"context"
    21  	"flag"
    22  	"net/http"
    23  	"os"
    24  	"os/signal"
    25  	"syscall"
    26  	"time"
    27  
    28  	"k8s.io/klog/v2"
    29  
    30  	"k8s.io/registry.k8s.io/cmd/archeio/internal/app"
    31  )
    32  
    33  func main() {
    34  	// klog setup
    35  	klog.InitFlags(nil)
    36  	flag.Parse()
    37  	defer klog.Flush()
    38  
    39  	// cloud run expects us to listen to HTTP on $PORT
    40  	// https://cloud.google.com/run/docs/container-contract#port
    41  	port := getEnv("PORT", "8080")
    42  
    43  	// make it possible to override k8s.gcr.io without rebuilding in the future
    44  	registryConfig := app.RegistryConfig{
    45  		UpstreamRegistryEndpoint: getEnv("UPSTREAM_REGISTRY_ENDPOINT", "https://us-central1-docker.pkg.dev"),
    46  		UpstreamRegistryPath:     getEnv("UPSTREAM_REGISTRY_PATH", "k8s-artifacts-prod/images"),
    47  		InfoURL:                  "https://github.com/kubernetes/registry.k8s.io",
    48  		PrivacyURL:               "https://www.linuxfoundation.org/privacy-policy/",
    49  		DefaultAWSBaseURL:        getEnv("DEFAULT_AWS_BASE_URL", "https://prod-registry-k8s-io-us-east-1.s3.dualstack.us-east-1.amazonaws.com"),
    50  	}
    51  
    52  	// configure server with reasonable timeout
    53  	// we only serve redirects, 10s should be sufficient
    54  	server := &http.Server{
    55  		Addr:              ":" + port,
    56  		Handler:           app.MakeHandler(registryConfig),
    57  		ReadTimeout:       10 * time.Second,
    58  		ReadHeaderTimeout: 2 * time.Second,
    59  	}
    60  
    61  	// signal handler for graceful shutdown
    62  	done := make(chan os.Signal, 1)
    63  	signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
    64  
    65  	// start serving
    66  	go func() {
    67  		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
    68  			klog.Fatal(err)
    69  		}
    70  	}()
    71  	klog.InfoS("listening", "port", port)
    72  	klog.InfoS("registry", "configuration", registryConfig)
    73  
    74  	// Graceful shutdown
    75  	<-done
    76  	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    77  	defer cancel()
    78  	if err := server.Shutdown(ctx); err != nil {
    79  		klog.Fatalf("Server didn't exit gracefully %v", err)
    80  	}
    81  }
    82  
    83  // getEnv returns defaultValue if key is not set, else the value of os.LookupEnv(key)
    84  func getEnv(key, defaultValue string) string {
    85  	if value, ok := os.LookupEnv(key); ok {
    86  		return value
    87  	}
    88  	return defaultValue
    89  }