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 }