github.com/yasker/longhorn-engine@v0.0.0-20160621014712-6ed6cfca0729/app/controller.go (about)

     1  package app
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"log"
     7  	"net/http"
     8  	"os"
     9  
    10  	"github.com/Sirupsen/logrus"
    11  	"github.com/codegangsta/cli"
    12  	"github.com/gorilla/handlers"
    13  	"github.com/rancher/longhorn/backend/dynamic"
    14  	"github.com/rancher/longhorn/backend/file"
    15  	"github.com/rancher/longhorn/backend/remote"
    16  	"github.com/rancher/longhorn/controller"
    17  	"github.com/rancher/longhorn/controller/rest"
    18  	"github.com/rancher/longhorn/types"
    19  	"github.com/rancher/longhorn/util"
    20  )
    21  
    22  var (
    23  	frontends = map[string]types.Frontend{}
    24  )
    25  
    26  func ControllerCmd() cli.Command {
    27  	return cli.Command{
    28  		Name: "controller",
    29  		Flags: []cli.Flag{
    30  			cli.StringFlag{
    31  				Name:  "listen",
    32  				Value: "localhost:9501",
    33  			},
    34  			cli.StringFlag{
    35  				Name:  "frontend",
    36  				Value: "",
    37  			},
    38  			cli.StringSliceFlag{
    39  				Name:  "enable-backend",
    40  				Value: (*cli.StringSlice)(&[]string{"tcp"}),
    41  			},
    42  			cli.StringSliceFlag{
    43  				Name: "replica",
    44  			},
    45  		},
    46  		Action: func(c *cli.Context) {
    47  			if err := startController(c); err != nil {
    48  				logrus.Fatalf("Error running controller command: %v.", err)
    49  			}
    50  		},
    51  	}
    52  }
    53  
    54  func startController(c *cli.Context) error {
    55  	if c.NArg() == 0 {
    56  		return errors.New("volume name is required")
    57  	}
    58  	name := c.Args()[0]
    59  
    60  	listen := c.String("listen")
    61  	backends := c.StringSlice("enable-backend")
    62  	replicas := c.StringSlice("replica")
    63  	frontendName := c.String("frontend")
    64  
    65  	factories := map[string]types.BackendFactory{}
    66  	for _, backend := range backends {
    67  		switch backend {
    68  		case "file":
    69  			factories[backend] = file.New()
    70  		case "tcp":
    71  			factories[backend] = remote.New()
    72  		default:
    73  			logrus.Fatalf("Unsupported backend: %s", backend)
    74  		}
    75  	}
    76  
    77  	var frontend types.Frontend
    78  	if frontendName != "" {
    79  		f, ok := frontends[frontendName]
    80  		if !ok {
    81  			return fmt.Errorf("Failed to find frontend: %s", frontendName)
    82  		}
    83  		frontend = f
    84  	}
    85  
    86  	control := controller.NewController(name, dynamic.New(factories), frontend)
    87  	server := rest.NewServer(control)
    88  	router := http.Handler(rest.NewRouter(server))
    89  
    90  	router = util.FilteredLoggingHandler(map[string]struct{}{
    91  		"/v1/volumes":  struct{}{},
    92  		"/v1/replicas": struct{}{},
    93  	}, os.Stdout, router)
    94  	router = handlers.ProxyHeaders(router)
    95  
    96  	if len(replicas) > 0 {
    97  		logrus.Infof("Starting with replicas %q", replicas)
    98  		if err := control.Start(replicas...); err != nil {
    99  			log.Fatal(err)
   100  		}
   101  	}
   102  
   103  	logrus.Infof("Listening on %s", listen)
   104  
   105  	addShutdown(func() {
   106  		control.Shutdown()
   107  	})
   108  
   109  	return http.ListenAndServe(listen, router)
   110  }