github.com/cloudposse/helm@v2.2.3+incompatible/cmd/tiller/tiller.go (about)

     1  /*
     2  Copyright 2016 The Kubernetes Authors All rights reserved.
     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 // import "k8s.io/helm/cmd/tiller"
    18  
    19  import (
    20  	"fmt"
    21  	"io/ioutil"
    22  	"log"
    23  	"net"
    24  	"net/http"
    25  	"os"
    26  	"strings"
    27  
    28  	"github.com/spf13/cobra"
    29  
    30  	"k8s.io/helm/pkg/kube"
    31  	"k8s.io/helm/pkg/proto/hapi/services"
    32  	"k8s.io/helm/pkg/storage"
    33  	"k8s.io/helm/pkg/storage/driver"
    34  	"k8s.io/helm/pkg/tiller"
    35  	"k8s.io/helm/pkg/tiller/environment"
    36  	"k8s.io/helm/pkg/version"
    37  )
    38  
    39  const (
    40  	storageMemory    = "memory"
    41  	storageConfigMap = "configmap"
    42  )
    43  
    44  // rootServer is the root gRPC server.
    45  //
    46  // Each gRPC service registers itself to this server during init().
    47  var rootServer = tiller.NewServer()
    48  
    49  // env is the default environment.
    50  //
    51  // Any changes to env should be done before rootServer.Serve() is called.
    52  var env = environment.New()
    53  
    54  var (
    55  	grpcAddr      = ":44134"
    56  	probeAddr     = ":44135"
    57  	traceAddr     = ":44136"
    58  	enableTracing = false
    59  	store         = storageConfigMap
    60  )
    61  
    62  const globalUsage = `The Kubernetes Helm server.
    63  
    64  Tiller is the server for Helm. It provides in-cluster resource management.
    65  
    66  By default, Tiller listens for gRPC connections on port 44134.
    67  `
    68  
    69  var rootCommand = &cobra.Command{
    70  	Use:   "tiller",
    71  	Short: "The Kubernetes Helm server.",
    72  	Long:  globalUsage,
    73  	Run:   start,
    74  }
    75  
    76  func init() {
    77  	log.SetFlags(log.Flags() | log.Lshortfile)
    78  }
    79  
    80  func main() {
    81  	p := rootCommand.PersistentFlags()
    82  	p.StringVarP(&grpcAddr, "listen", "l", ":44134", "address:port to listen on")
    83  	p.StringVar(&store, "storage", storageConfigMap, "storage driver to use. One of 'configmap' or 'memory'")
    84  	p.BoolVar(&enableTracing, "trace", false, "enable rpc tracing")
    85  
    86  	if err := rootCommand.Execute(); err != nil {
    87  		fmt.Fprint(os.Stderr, err)
    88  		os.Exit(1)
    89  	}
    90  }
    91  
    92  func start(c *cobra.Command, args []string) {
    93  	clientset, err := kube.New(nil).ClientSet()
    94  	if err != nil {
    95  		fmt.Fprintf(os.Stderr, "Cannot initialize Kubernetes connection: %s\n", err)
    96  		os.Exit(1)
    97  	}
    98  
    99  	switch store {
   100  	case storageMemory:
   101  		env.Releases = storage.Init(driver.NewMemory())
   102  	case storageConfigMap:
   103  		env.Releases = storage.Init(driver.NewConfigMaps(clientset.Core().ConfigMaps(namespace())))
   104  	}
   105  
   106  	lstn, err := net.Listen("tcp", grpcAddr)
   107  	if err != nil {
   108  		fmt.Fprintf(os.Stderr, "Server died: %s\n", err)
   109  		os.Exit(1)
   110  	}
   111  
   112  	fmt.Printf("Starting Tiller %s\n", version.GetVersion())
   113  	fmt.Printf("GRPC listening on %s\n", grpcAddr)
   114  	fmt.Printf("Probes listening on %s\n", probeAddr)
   115  	fmt.Printf("Storage driver is %s\n", env.Releases.Name())
   116  
   117  	if enableTracing {
   118  		startTracing(traceAddr)
   119  	}
   120  
   121  	srvErrCh := make(chan error)
   122  	probeErrCh := make(chan error)
   123  	go func() {
   124  		svc := tiller.NewReleaseServer(env, clientset)
   125  		services.RegisterReleaseServiceServer(rootServer, svc)
   126  		if err := rootServer.Serve(lstn); err != nil {
   127  			srvErrCh <- err
   128  		}
   129  	}()
   130  
   131  	go func() {
   132  		mux := newProbesMux()
   133  		if err := http.ListenAndServe(probeAddr, mux); err != nil {
   134  			probeErrCh <- err
   135  		}
   136  	}()
   137  
   138  	select {
   139  	case err := <-srvErrCh:
   140  		fmt.Fprintf(os.Stderr, "Server died: %s\n", err)
   141  		os.Exit(1)
   142  	case err := <-probeErrCh:
   143  		fmt.Fprintf(os.Stderr, "Probes server died: %s\n", err)
   144  	}
   145  }
   146  
   147  // namespace returns the namespace of tiller
   148  func namespace() string {
   149  	if ns := os.Getenv("TILLER_NAMESPACE"); ns != "" {
   150  		return ns
   151  	}
   152  
   153  	// Fall back to the namespace associated with the service account token, if available
   154  	if data, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil {
   155  		if ns := strings.TrimSpace(string(data)); len(ns) > 0 {
   156  			return ns
   157  		}
   158  	}
   159  
   160  	return environment.DefaultTillerNamespace
   161  }