func Config(sous *core.Sous, args []string) { if len(args) == 0 || len(args) > 2 { cli.Fatalf("usage: sous config <key> [<new-value>]") } if len(args) == 1 { if v, ok := config.Properties()[args[0]]; ok { cli.Outf(v) cli.Success() } cli.Fatalf("Key %s not found", args[0]) } config.Set(args[0], args[1]) cli.Logf("Successfully set %s to %s", args[0], args[1]) cli.Success() }
func Ls(sous *core.Sous, args []string) { //globalFlag := lsFlags.Bool("g", false, "global: list files in all projects sous has built") //lsFlags.Parse(args) //global := *globalFlag args = lsFlags.Args() if len(args) != 0 { cli.Fatalf("sous ls does not accept any arguments") } _, context := sous.AssembleTargetContext("app") cli.Outf(" ===> Images") images := sous.LsImages(context) if len(images) == 0 { cli.Logf(" no images for this project") } for _, image := range images { cli.Logf(" %s:%s", image.Name, image.Tag) } cli.Outf(" ===> Containers") containers := sous.LsContainers(context) if len(containers) == 0 { cli.Logf(" no containers for this project") } for _, container := range containers { cli.Logf(" %s (%s)", container.Name(), container.CID()) } cli.Success() }
func Contracts(sous *core.Sous, args []string) { contractsFlags.Parse(args) args = contractsFlags.Args() timeout := *timeoutFlag targetName := "app" if len(args) != 0 { targetName = args[0] } core.RequireGit() core.RequireDocker() if *dockerImage != "" { cli.Fatalf("-image flag not yet implemented") } target, context := sous.AssembleTargetContext(targetName) sous.RunTarget(target, context) cli.Logf("=> Running Contracts") cli.Logf(`=> **TIP:** Open another terminal in this directory and type **sous logs -f**`) taskHost := core.DivineTaskHost() port0, err := ports.GetFreePort() if err != nil { cli.Fatalf("Unable to get free port: %s", err) } dr := docker.NewRun(context.DockerTag()) dr.AddEnv("PORT0", strconv.Itoa(port0)) dr.AddEnv("TASK_HOST", taskHost) dr.StdoutFile = context.FilePath("stdout") dr.StderrFile = context.FilePath("stderr") container, err := dr.Background().Start() if err != nil { cli.Fatalf("Unable to start container: %s", err) } cli.AddCleanupTask(func() error { return container.KillIfRunning() }) failed := 0 for _, c := range theContracts { cli.Logf(`===> CHECKING CONTRACT: "%s"`, c.Name) cli.Logf(`===> Description: %s`, c.Desc(dr)) if c.Tips != nil { cli.Logf("===> **TIPS for this contract:**") cli.LogBulletList(" -", c.Tips(dr)) } failed += within(timeout, func() bool { return c.Premise(dr) }) } if failed != 0 { cli.Fatalf("%d contracts failed.", failed) } cli.Success() }
func Update(sous *core.Sous, args []string) { key := "last-update-check" if err := config.Update(); err != nil { cli.Fatal() } config.Set(key, time.Now().Format(time.RFC3339)) cli.Success() }
func TaskPort(sous *core.Sous, args []string) { port0, err := ports.GetFreePort() if err != nil { cli.Fatalf("Unable to get free port: %s", err) } cli.Outf("%d", port0) cli.Success() }
func Clean(sous *core.Sous, args []string) { _, context := sous.AssembleTargetContext("app") cleanContainersSucceeded := cleanContainers(sous, context) cleanImagesSucceeded := cleanImages(sous, context) if cleanContainersSucceeded && cleanImagesSucceeded { cli.Success() } cli.Fatal() }
func BuildPath(sous *core.Sous, args []string) { target := "app" if len(args) != 0 { target = args[0] } _, context := sous.AssembleTargetContext(target) fmt.Println(path.Resolve(path.BaseDir(context.BaseDir()))) cli.Success() }
func Dockerfile(sous *core.Sous, args []string) { targetName := "app" if len(args) != 0 { targetName = args[0] } target, context := sous.AssembleTargetContext(targetName) cli.Outf(sous.Dockerfile(target, context).Render()) cli.Success() }
func Image(sous *core.Sous, args []string) { target := "app" if len(args) != 0 { target = args[0] } _, context := sous.AssembleTargetContext(target) if context.BuildNumber() == 0 { cli.Fatalf("no builds yet") } cli.Outf(context.DockerTag()) cli.Success() }
func Contracts(sous *core.Sous, args []string) { contractsFlags.Parse(args) args = contractsFlags.Args() state, err := deploy.Parse(".") if err != nil { cli.Fatalf(err.Error()) } _ = state.Contracts cli.Success() }
func ParseState(sous *core.Sous, args []string) { stateDir := getStateDir(args) state, err := deploy.Parse(stateDir) if err != nil { cli.Fatalf("%s", err) } merged, err := state.Merge() if err != nil { cli.Fatalf("%s", err) } out, err := yaml.Marshal(merged) if err != nil { cli.Fatalf("%s", err) } cli.Outf(string(out)) cli.Success() }
func Logs(sous *core.Sous, args []string) { logsFlags.Parse(args) args = logsFlags.Args() target := "app" if len(args) != 0 { target = args[0] } _, context := sous.AssembleTargetContext(target) out := makeTail(context.FilePath("stdout"), *follow, *lines, os.Stdout) err := makeTail(context.FilePath("stderr"), *follow, *lines, os.Stderr) if err := out.Start(); err != nil { cli.Fatalf("Unable to begin tailing %s", context.FilePath("stdout")) } if err := err.Start(); err != nil { cli.Fatalf("Unable to begin tailing %s", context.FilePath("stderr")) } c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, syscall.SIGTERM) if *follow { <-c out.Process.Signal(os.Interrupt) err.Process.Signal(os.Interrupt) } errs := []string{} if err := out.Wait(); err != nil { errs = append(errs, err.Error()) } if err := err.Wait(); err != nil { errs = append(errs, err.Error()) } if !*follow { if len(errs) != 0 { cli.Fatalf("Done with errors: %s", strings.Join(errs, ", ")) } } cli.Success() }
func Run(sous *core.Sous, args []string) { targetName := "app" if len(args) != 0 { targetName = args[0] } core.RequireGit() core.RequireDocker() target, context := sous.AssembleTargetContext(targetName) runner, ok := target.(core.ContainerTarget) if !ok { cli.Fatalf("Target %s does not support running.", target.Name()) } rebuilt, _ := sous.RunTarget(target, context) dr, _ := sous.RunContainerTarget(runner, context, rebuilt) if exitCode := dr.ExitCode(); exitCode != 0 { cli.Logf("Docker container exited with code %d", exitCode) cli.Exit(exitCode) } cli.Success() }
func Detect(sous *core.Sous, args []string) { pack := core.DetectProjectType(sous.Packs) if pack == nil { fmt.Println("no sous-compatible project detected") os.Exit(1) } if fatal := core.CheckForProblems(pack); fatal { cli.Fatalf("Detected a %s project with fatal errors.", pack) } c := core.GetContext("app") desc := pack.AppDesc() cli.Outf("Detected a %s; which supports the following targets...", desc) for _, target := range pack.Targets() { if err := target.Check(); err != nil { cli.Outf("\t%s \t✘ %s", target, err) continue } cli.Outf("\t%s \t✔︎", target) } cli.Outf("Build Version: %s", c.BuildVersion) cli.Success() }
func Help(sous *core.Sous, args []string) { if len(args) != 0 { command := args[0] if c, ok := sous.Commands[command]; ok { if c.HelpFunc != nil { fmt.Println(c.HelpFunc()) os.Exit(0) } cli.Fatalf("Command %s does not have any help yet.", command) } cli.Fatalf("There is no command called %s; try `sous help`\n", command) } cli.Outf(`Sous is your personal sous chef for engineering tasks. It can help with building, configuring, and deploying your code for OpenTable's Mesos Platform. Commands:`) printCommands(sous) cli.Outf("") cli.Outf("Tip: for help with any command, use `sous help <COMMAND>`") cli.Success() }
func TaskHost(sous *core.Sous, args []string) { cli.Outf("%s", core.DivineTaskHost()) cli.Success() }
func Version(sous *core.Sous, args []string) { cli.Outf("Sous version %s %s/%s", sous.Version, sous.OS, sous.Arch) cli.Outf("Revision: %s", sous.Revision) cli.Success() }