github.com/devcamcar/cli@v0.0.0-20181107134215-706a05759d18/commands/start.go (about)

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os"
     7  	"os/exec"
     8  	"os/signal"
     9  	"path/filepath"
    10  	"syscall"
    11  
    12  	"github.com/fnproject/cli/common"
    13  	"github.com/fnproject/cli/config"
    14  	"github.com/urfave/cli"
    15  )
    16  
    17  // StartCommand returns start server cli.command
    18  func StartCommand() cli.Command {
    19  	return cli.Command{
    20  		Name:        "start",
    21  		Usage:       "Start a local Fn server",
    22  		Category:    "SERVER COMMANDS",
    23  		Description: "This command starts a local Fn server by downloading its docker image.",
    24  		Action:      start,
    25  		Flags: []cli.Flag{
    26  			cli.StringFlag{
    27  				Name:  "log-level",
    28  				Usage: "--log-level debug to enable debugging",
    29  			},
    30  			cli.BoolFlag{
    31  				Name:  "detach, d",
    32  				Usage: "Run container in background.",
    33  			},
    34  			cli.StringFlag{
    35  				Name:  "env-file",
    36  				Usage: "Path to Fn server configuration file.",
    37  			},
    38  			cli.IntFlag{
    39  				Name:  "port, p",
    40  				Value: 8080,
    41  				Usage: "Specify port number to bind to on the host.",
    42  			},
    43  		},
    44  	}
    45  }
    46  
    47  func start(c *cli.Context) error {
    48  	var fnDir string
    49  	home := config.GetHomeDir()
    50  
    51  	if c.String("data-dir") != "" {
    52  		fnDir = c.String("data-dir")
    53  	} else {
    54  		fnDir = filepath.Join(home, ".fn")
    55  	}
    56  
    57  	args := []string{"run", "--rm", "-i",
    58  		"--name", "fnserver",
    59  		"-v", fmt.Sprintf("%s/iofs:/iofs", fnDir),
    60  		"-e", fmt.Sprintf("FN_IOFS_DOCKER_PATH=%s/iofs", fnDir),
    61  		"-e", "FN_IOFS_PATH=/iofs",
    62  		"-v", fmt.Sprintf("%s/data:/app/data", fnDir),
    63  		"-v", "/var/run/docker.sock:/var/run/docker.sock",
    64  		"--privileged",
    65  		"-p", fmt.Sprintf("%d:8080", c.Int("port")),
    66  		"--entrypoint", "./fnserver",
    67  	}
    68  	if c.String("log-level") != "" {
    69  		args = append(args, "-e", fmt.Sprintf("FN_LOG_LEVEL=%v", c.String("log-level")))
    70  	}
    71  	if c.String("env-file") != "" {
    72  		args = append(args, "--env-file", c.String("env-file"))
    73  	}
    74  	if c.Bool("detach") {
    75  		args = append(args, "-d")
    76  	}
    77  	args = append(args, common.FunctionsDockerImage)
    78  	cmd := exec.Command("docker", args...)
    79  	cmd.Stdout = os.Stdout
    80  	cmd.Stderr = os.Stderr
    81  	err := cmd.Start()
    82  	if err != nil {
    83  		log.Fatalln("Starting command failed:", err)
    84  	}
    85  
    86  	done := make(chan error, 1)
    87  	go func() {
    88  		done <- cmd.Wait()
    89  	}()
    90  	// catch ctrl-c and kill
    91  	sigC := make(chan os.Signal, 2)
    92  	signal.Notify(sigC, os.Interrupt, syscall.SIGTERM)
    93  
    94  	for {
    95  		select {
    96  		case <-sigC:
    97  			log.Println("Interrupt caught, exiting")
    98  			err = cmd.Process.Signal(syscall.SIGTERM)
    99  			if err != nil {
   100  				log.Println("Error: could not kill process:", err)
   101  				return err
   102  			}
   103  		case err := <-done:
   104  			if err != nil {
   105  				log.Println("Error: processed finished with error", err)
   106  			}
   107  		}
   108  		return err
   109  	}
   110  }