func TillerHealthHandler() func(writer http.ResponseWriter, request *http.Request) {
	return func(writer http.ResponseWriter, request *http.Request) {
		if TillerProbeConnectAddress == "" {
			writer.WriteHeader(http.StatusInternalServerError)
			_, _ = writer.Write([]byte("Error request tiller: not started yet."))
			return
		}
		tillerUrl := fmt.Sprintf("http://%s/liveness", TillerProbeConnectAddress)
		res, err := http.Get(tillerUrl)
		if err != nil {
			writer.WriteHeader(http.StatusInternalServerError)
			_, _ = writer.Write([]byte(fmt.Sprintf("Error request tiller: %v", err)))
			return
		}
		tillerLivenessBody, err := ioutil.ReadAll(res.Body)
		_ = res.Body.Close()
		if err != nil {
			writer.WriteHeader(http.StatusInternalServerError)
			_, _ = writer.Write([]byte(fmt.Sprintf("Error reading tiller response: %v", err)))
			return
		}
		writer.WriteHeader(http.StatusOK)
		_, _ = writer.Write(tillerLivenessBody)
	}
}
TillerHealthHandler translates tiller's /liveness response
package helm2
import (
	"bufio"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"time"
	log "github.com/sirupsen/logrus"
	"github.com/flant/shell-operator/pkg/utils/labels"
)
var TillerPath = "tiller"
const TillerWaitTimeoutSeconds = 2
const TillerWaitRetryDelay = 250 * time.Millisecond
const TillerWaitTimeout = 10 * time.Second  
type TillerOptions struct {
	Namespace          string
	HistoryMax         int32
	ListenAddress      string
	ListenPort         int32
	ProbeListenAddress string
	ProbeListenPort    int32
}
var TillerConnectAddress string
var TillerProbeConnectAddress string
func InitTillerProcess(options TillerOptions) error {
	logLabels := map[string]string{
		"operator.component": "tiller",
	}
	logEntry := log.WithFields(utils.LabelsToLogFields(logLabels))
	listenAddr := fmt.Sprintf("%s:%d", options.ListenAddress, options.ListenPort)
	probeListenAddr := fmt.Sprintf("%s:%d", options.ProbeListenAddress, options.ProbeListenPort)
	err := CheckListenAddresses(listenAddr, probeListenAddr)
	if err != nil {
		newListenAddr, newProbeListenAddr, newErr := GetOpenPortsPair(listenAddr, probeListenAddr)
		if newErr != nil {
			return fmt.Errorf("choose open ports for tiller: %v", err)
		}
		listenAddr = newListenAddr
		probeListenAddr = newProbeListenAddr
	}
	env := []string{
		fmt.Sprintf("TILLER_NAMESPACE=%s", options.Namespace),
		fmt.Sprintf("TILLER_HISTORY_MAX=%d", options.HistoryMax),
	}
	args := []string{
		"-listen",
		listenAddr,
		"-probe-listen",
		probeListenAddr,
	}
	tillerCmd := exec.Command(TillerPath, args...)
	tillerCmd.Env = append(os.Environ(), env...)
	tillerCmd.Dir = "/"
	err = StartAndLogLines(tillerCmd, logLabels)
	if err != nil {
		return fmt.Errorf("start tiller subprocess with -listen=%s -probeListen=%s: %v", listenAddr, probeListenAddr, err)
	}
	TillerConnectAddress = listenAddr
	TillerProbeConnectAddress = probeListenAddr
	logEntry.Infof("Tiller starts with -listen=%s -probeListen=%s", listenAddr, probeListenAddr)
	go func() {
		err := tillerCmd.Wait()
		TillerExitHandler(err, logEntry)
	}()
	return WaitTillerReady(listenAddr, logEntry)
}
func WaitTillerReady(addr string, logEntry *log.Entry) error {
	tillerWaitRetries := int(TillerWaitTimeout / ((TillerWaitTimeoutSeconds * time.Second) + TillerWaitRetryDelay))
	retries := 0
	for {
		cliHelm := &Helm2Client{}
		stdout, stderr, err := cliHelm.Cmd("version", "--tiller-connection-timeout", fmt.Sprintf("%d", TillerWaitTimeoutSeconds))
		if err != nil {
			logEntry.WithField("stdout", stdout).
				WithField("stderr", stderr).
				Warnf("Unable to get tiller version: %v", err)
			time.Sleep(TillerWaitRetryDelay)
		} else {
			logEntry.WithField("stdout", stdout).
				WithField("stderr", stderr).
				Debugf("Output of helm version")
			logEntry.Infof("Tiller started and is available")
			break
		}
		retries += 1
		if retries > tillerWaitRetries {
			return fmt.Errorf("wait tiller timeout: wait more than %s", TillerWaitTimeout.String())
		}
	}
	return nil
}
func TillerExitHandler(err error, logEntry *log.Entry) {
	if err != nil {
		logEntry.Errorf("Tiller process exited, now stop. Wait error: %v", err)
	} else {
		logEntry.Errorf("Tiller process exited, now stop.")
	}
	os.Exit(1)
}