github.com/tonto/cli@v0.0.0-20180104210444-aec958fa47db/start.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os"
     7  	"os/exec"
     8  	"os/signal"
     9  	"syscall"
    10  
    11  	"github.com/urfave/cli"
    12  )
    13  
    14  func startCmd() cli.Command {
    15  	return cli.Command{
    16  		Name:   "start",
    17  		Usage:  "start a functions server",
    18  		Action: start,
    19  		Flags: []cli.Flag{
    20  			cli.StringFlag{
    21  				Name:  "log-level",
    22  				Usage: "--log-level DEBUG to enable debugging",
    23  			},
    24  			cli.BoolFlag{
    25  				Name:  "detach, d",
    26  				Usage: "Run container in background.",
    27  			},
    28  			cli.StringFlag{
    29  				Name: "env-file",
    30  				Usage: "Path to Fn server configuration file.",
    31  			},
    32  		},
    33  	}
    34  }
    35  
    36  func start(c *cli.Context) error {
    37  	wd, err := os.Getwd()
    38  	if err != nil {
    39  		log.Fatalln("Getwd failed:", err)
    40  	}
    41  	args := []string{"run", "--rm", "-i",
    42  		"--name", "fnserver",
    43  		"-v", fmt.Sprintf("%s/data:/app/data", wd),
    44  		"-v", "/var/run/docker.sock:/var/run/docker.sock",
    45  		"--privileged",
    46  		"-p", "8080:8080",
    47  	}
    48  	if c.String("log-level") != "" {
    49  		args = append(args, "-e", fmt.Sprintf("GIN_MODE=%v", c.String("log-level")))
    50  	}
    51  	if c.String("env-file") != ""{
    52  		args = append(args, "--env-file", c.String("env-file"))
    53  	}
    54  	if c.Bool("detach") {
    55  		args = append(args, "-d")
    56  	}
    57  	args = append(args, functionsDockerImage)
    58  	cmd := exec.Command("docker", args...)
    59  	cmd.Stdout = os.Stdout
    60  	cmd.Stderr = os.Stderr
    61  	err = cmd.Start()
    62  	if err != nil {
    63  		log.Fatalln("starting command failed:", err)
    64  	}
    65  
    66  	done := make(chan error, 1)
    67  	go func() {
    68  		done <- cmd.Wait()
    69  	}()
    70  	// catch ctrl-c and kill
    71  	sigC := make(chan os.Signal, 2)
    72  	signal.Notify(sigC, os.Interrupt, syscall.SIGTERM)
    73  
    74  	for {
    75  		select {
    76  		case <-sigC:
    77  			log.Println("interrupt caught, exiting")
    78  			err = cmd.Process.Signal(syscall.SIGTERM)
    79  			if err != nil {
    80  				log.Println("error: could not kill process:", err)
    81  				return err
    82  			}
    83  		case err := <-done:
    84  			if err != nil {
    85  				log.Println("error: processed finished with error", err)
    86  			}
    87  			return err
    88  		}
    89  	}
    90  
    91  	return nil
    92  }