github.com/argoproj/argo-cd/v3@v3.2.1/cmd/argocd-commit-server/commands/argocd_commit_server.go (about)

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"net/http"
     7  	"os"
     8  	"os/signal"
     9  	"sync"
    10  	"syscall"
    11  
    12  	log "github.com/sirupsen/logrus"
    13  	"github.com/spf13/cobra"
    14  	"google.golang.org/grpc/health/grpc_health_v1"
    15  
    16  	cmdutil "github.com/argoproj/argo-cd/v3/cmd/util"
    17  	"github.com/argoproj/argo-cd/v3/commitserver"
    18  	"github.com/argoproj/argo-cd/v3/commitserver/apiclient"
    19  	"github.com/argoproj/argo-cd/v3/commitserver/metrics"
    20  	"github.com/argoproj/argo-cd/v3/common"
    21  	"github.com/argoproj/argo-cd/v3/util/askpass"
    22  	"github.com/argoproj/argo-cd/v3/util/cli"
    23  	"github.com/argoproj/argo-cd/v3/util/env"
    24  	"github.com/argoproj/argo-cd/v3/util/errors"
    25  	"github.com/argoproj/argo-cd/v3/util/healthz"
    26  	utilio "github.com/argoproj/argo-cd/v3/util/io"
    27  )
    28  
    29  // NewCommand returns a new instance of an argocd-commit-server command
    30  func NewCommand() *cobra.Command {
    31  	var (
    32  		listenHost  string
    33  		listenPort  int
    34  		metricsPort int
    35  		metricsHost string
    36  	)
    37  	command := &cobra.Command{
    38  		Use:   "argocd-commit-server",
    39  		Short: "Run Argo CD Commit Server",
    40  		Long:  "Argo CD Commit Server is an internal service which commits and pushes hydrated manifests to git. This command runs Commit Server in the foreground.",
    41  		RunE: func(_ *cobra.Command, _ []string) error {
    42  			vers := common.GetVersion()
    43  			vers.LogStartupInfo(
    44  				"Argo CD Commit Server",
    45  				map[string]any{
    46  					"port": listenPort,
    47  				},
    48  			)
    49  
    50  			cli.SetLogFormat(cmdutil.LogFormat)
    51  			cli.SetLogLevel(cmdutil.LogLevel)
    52  
    53  			metricsServer := metrics.NewMetricsServer()
    54  			http.Handle("/metrics", metricsServer.GetHandler())
    55  			go func() { errors.CheckError(http.ListenAndServe(fmt.Sprintf("%s:%d", metricsHost, metricsPort), nil)) }()
    56  
    57  			askPassServer := askpass.NewServer(askpass.CommitServerSocketPath)
    58  			go func() { errors.CheckError(askPassServer.Run()) }()
    59  
    60  			server := commitserver.NewServer(askPassServer, metricsServer)
    61  			grpc := server.CreateGRPC()
    62  
    63  			listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", listenHost, listenPort))
    64  			errors.CheckError(err)
    65  
    66  			healthz.ServeHealthCheck(http.DefaultServeMux, func(r *http.Request) error {
    67  				if val, ok := r.URL.Query()["full"]; ok && len(val) > 0 && val[0] == "true" {
    68  					// connect to itself to make sure commit server is able to serve connection
    69  					// used by liveness probe to auto restart commit server
    70  					conn, err := apiclient.NewConnection(fmt.Sprintf("localhost:%d", listenPort))
    71  					if err != nil {
    72  						return err
    73  					}
    74  					defer utilio.Close(conn)
    75  					client := grpc_health_v1.NewHealthClient(conn)
    76  					res, err := client.Check(r.Context(), &grpc_health_v1.HealthCheckRequest{})
    77  					if err != nil {
    78  						return err
    79  					}
    80  					if res.Status != grpc_health_v1.HealthCheckResponse_SERVING {
    81  						return fmt.Errorf("grpc health check status is '%v'", res.Status)
    82  					}
    83  					return nil
    84  				}
    85  				return nil
    86  			})
    87  
    88  			// Graceful shutdown code adapted from here: https://gist.github.com/embano1/e0bf49d24f1cdd07cffad93097c04f0a
    89  			sigCh := make(chan os.Signal, 1)
    90  			signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)
    91  			wg := sync.WaitGroup{}
    92  			wg.Add(1)
    93  			go func() {
    94  				s := <-sigCh
    95  				log.Printf("got signal %v, attempting graceful shutdown", s)
    96  				grpc.GracefulStop()
    97  				wg.Done()
    98  			}()
    99  
   100  			log.Println("starting grpc server")
   101  			err = grpc.Serve(listener)
   102  			errors.CheckError(err)
   103  			wg.Wait()
   104  			log.Println("clean shutdown")
   105  
   106  			return nil
   107  		},
   108  	}
   109  	command.Flags().StringVar(&cmdutil.LogFormat, "logformat", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LOGFORMAT", "json"), "Set the logging format. One of: json|text")
   110  	command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LOGLEVEL", "info"), "Set the logging level. One of: debug|info|warn|error")
   111  	command.Flags().StringVar(&listenHost, "address", env.StringFromEnv("ARGOCD_COMMIT_SERVER_LISTEN_ADDRESS", common.DefaultAddressCommitServer), "Listen on given address for incoming connections")
   112  	command.Flags().IntVar(&listenPort, "port", common.DefaultPortCommitServer, "Listen on given port for incoming connections")
   113  	command.Flags().StringVar(&metricsHost, "metrics-address", env.StringFromEnv("ARGOCD_COMMIT_SERVER_METRICS_LISTEN_ADDRESS", common.DefaultAddressCommitServerMetrics), "Listen on given address for metrics")
   114  	command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortCommitServerMetrics, "Start metrics server on given port")
   115  
   116  	return command
   117  }