func upload(c *cli.Context) { if c.NArg() < 2 || c.NArg() > 3 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } localPath := c.Args().Get(0) versionDetails, err := utils.CreateVersionDetails(c.Args().Get(1)) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } uploadPath := c.Args().Get(2) if strings.HasPrefix(uploadPath, "/") { uploadPath = uploadPath[1:] } uploadFlags, err := createUploadFlags(c) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } uploaded, failed, err := commands.Upload(versionDetails, localPath, uploadPath, uploadFlags) cliutils.ExitOnErr(err) if failed > 0 { if uploaded > 0 { cliutils.Exit(cliutils.ExitCodeWarning, "") } cliutils.Exit(cliutils.ExitCodeError, "") } }
func getArguments(c *cli.Context) (string, string) { if c.NArg() != 2 { showError(c, "render arguments must be exactly 2 (input scene file and output image file)") } arguments := []string(c.Args()) return arguments[0], arguments[1] }
func logs(c *cli.Context) { bintrayDetails, err := createBintrayDetails(c, true) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } if c.NArg() == 1 { packageDetails, err := utils.CreatePackageDetails(c.Args().Get(0)) cliutils.ExitOnErr(err) err = commands.LogsList(packageDetails, bintrayDetails) cliutils.ExitOnErr(err) } else if c.NArg() == 3 { if c.Args().Get(0) == "download" { packageDetails, err := utils.CreatePackageDetails(c.Args().Get(1)) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } err = commands.DownloadLog(packageDetails, c.Args().Get(2), bintrayDetails) cliutils.ExitOnErr(err) } else { cliutils.Exit(cliutils.ExitCodeError, "Unkown argument "+c.Args().Get(0)+". "+cliutils.GetDocumentationMessage()) } } else { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } }
func DeletePolicy(c *cli.Context) error { unix, target, err := processClientTarget(c) if err != nil { return err } if unix { return noUnix } else { var name string if c.NArg() > 0 { name = c.Args()[0] } client := &http.Client{} req, err := http.NewRequest("DELETE", fmt.Sprintf("http://%s/policy/%s", target, name), nil) if err != nil { log.Fatal(err) } resp, err := client.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) fmt.Printf("%s", body) } return nil }
func handleStage(ctx *cli.Context, client *daemon.Client) error { filePath, err := filepath.Abs(ctx.Args().First()) if err != nil { return ExitCode{ UnknownError, fmt.Sprintf("Unable to make abs path: %v: %v", filePath, err), } } // Assume "/file.png" for file.png as repo path, if none given. repoPath := "/" + filepath.Base(filePath) if ctx.NArg() > 1 { repoPath = ctx.Args()[1] } if err := client.Stage(filePath, repoPath); err != nil { return ExitCode{ UnknownError, fmt.Sprintf("Could not stage file: %v: %v", filePath, err), } } fmt.Println(repoPath) return nil }
func deleteVersion(c *cli.Context) { if c.NArg() != 1 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } versionDetails, err := utils.CreateVersionDetails(c.Args().Get(0)) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } bintrayDetails, err := createBintrayDetails(c, true) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } if !c.Bool("quiet") { var confirm string fmt.Print("Delete version " + versionDetails.Version + " of package " + versionDetails.Package + "? (y/n): ") fmt.Scanln(&confirm) if !cliutils.ConfirmAnswer(confirm) { return } } err = commands.DeleteVersion(versionDetails, bintrayDetails) cliutils.ExitOnErr(err) }
func CheckAutocomplete(commands []string, c *cli.Context) { if c.NArg() > 0 { return } for _, command := range commands { fmt.Println(command) } }
func appSwitchAction(c *cli.Context) { if c.NArg() != 1 { log.Fatal("Usage: lean app switch <app-name>") } appName := c.Args()[0] utils.CheckError(apps.SwitchApp("", appName)) }
func rmReplica(c *cli.Context) error { if c.NArg() == 0 { return errors.New("replica address is required") } replica := c.Args()[0] controllerClient := getCli(c) _, err := controllerClient.DeleteReplica(replica) return err }
func buildDistributeCmd(c *cli.Context) { if c.NArg() != 3 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } buildDistributeFlags, err := createBuildDistributionFlags(c) if err != nil { cliutils.ExitOnErr(err) } err = commands.BuildDistribute(c.Args().Get(0), c.Args().Get(1), c.Args().Get(2), buildDistributeFlags) cliutils.ExitOnErr(err) }
func signUrl(c *cli.Context) { if c.NArg() != 1 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } urlSigningDetails, err := utils.CreatePathDetails(c.Args().Get(0)) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } urlSigningFlags, err := createUrlSigningFlags(c) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } err = commands.SignVersion(urlSigningDetails, urlSigningFlags) cliutils.ExitOnErr(err) }
func updatePackage(c *cli.Context) { if c.NArg() != 1 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } packageDetails, err := utils.CreatePackageDetails(c.Args().Get(0)) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } packageFlags, err := createPackageFlags(c) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } err = commands.UpdatePackage(packageDetails, packageFlags) cliutils.ExitOnErr(err) }
func gpgSignVersion(c *cli.Context) { if c.NArg() != 1 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } versionDetails, err := utils.CreateVersionDetails(c.Args().Get(0)) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } flags, err := createBintrayDetails(c, true) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } err = commands.GpgSignVersion(versionDetails, c.String("passphrase"), flags) cliutils.ExitOnErr(err) }
func publishVersion(c *cli.Context) { if c.NArg() != 1 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } versionDetails, err := utils.CreateVersionDetails(c.Args().Get(0)) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } bintrayDetails, err := createBintrayDetails(c, true) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } err = commands.PublishVersion(versionDetails, bintrayDetails) cliutils.ExitOnErr(err) }
func createVersion(c *cli.Context) { if c.NArg() != 1 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments "+cliutils.GetDocumentationMessage()) } versionDetails, err := utils.CreateVersionDetails(c.Args().Get(0)) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } versionFlags, err := createVersionFlags(c, "") if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } err = commands.CreateVersion(versionDetails, versionFlags) cliutils.ExitOnErr(err) }
func handleList(ctx *cli.Context, client *daemon.Client) error { path := "/" if ctx.NArg() > 0 { path = prefixSlash(ctx.Args().First()) } depth := ctx.Int("depth") if ctx.Bool("recursive") { depth = -1 } entries, err := client.List(path, depth) if err != nil { return ExitCode{ UnknownError, fmt.Sprintf("ls: %v", err), } } for _, entry := range entries { modTime := time.Time{} if err := modTime.UnmarshalText(entry.ModTime); err != nil { log.Warningf("Could not parse mtime (%s): %v", entry.ModTime, err) continue } fmt.Printf( "%s\t%s\t%s\n", colors.Colorize( humanize.Bytes(uint64(entry.NodeSize)), colors.Green, ), colors.Colorize( humanize.Time(modTime), colors.Cyan, ), colors.Colorize( entry.Path, colors.Magenta, ), ) } return nil }
func stream(c *cli.Context) { bintrayDetails, err := createBintrayDetails(c, true) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } if c.NArg() != 1 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } streamDetails := &commands.StreamDetails{ BintrayDetails: bintrayDetails, Subject: c.Args().Get(0), Include: c.String("include"), } err = commands.Stream(streamDetails, os.Stdout) if err != nil { cliutils.Exit(cliutils.ExitCodeError, "") } }
func downloadFile(c *cli.Context) { if c.NArg() < 1 || c.NArg() > 2 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } pathDetails, err := utils.CreatePathDetails(c.Args().Get(0)) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } targetPath := c.Args().Get(1) if strings.HasPrefix(targetPath, "/") { targetPath = targetPath[1:] } flags, err := createDownloadFlags(c) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } err = commands.DownloadFile(pathDetails, targetPath, flags) cliutils.ExitOnErr(err) }
func uploadCmd(c *cli.Context) { if c.NArg() > 0 && c.IsSet("spec") { cliutils.Exit(cliutils.ExitCodeError, "No arguments should be sent when the spec option is used. "+cliutils.GetDocumentationMessage()) } if !(c.NArg() == 2 || (c.NArg() == 0 && c.IsSet("spec"))) { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } var uploadSpec *utils.SpecFiles if c.IsSet("spec") { var err error uploadSpec, err = getUploadSpec(c) cliutils.ExitOnErr(err) } else { uploadSpec = createDefaultUploadSpec(c) } flags, err := createUploadFlags(c) cliutils.ExitOnErr(err) uploaded, failed, err := commands.Upload(uploadSpec, flags) cliutils.ExitOnErr(err) if failed > 0 { if uploaded > 0 { cliutils.Exit(cliutils.ExitCodeWarning, "") } cliutils.Exit(cliutils.ExitCodeError, "") } }
func searchCmd(c *cli.Context) { if c.NArg() > 0 && c.IsSet("spec") { cliutils.Exit(cliutils.ExitCodeError, "No arguments should be sent when the spec option is used. "+cliutils.GetDocumentationMessage()) } if !(c.NArg() == 1 || (c.NArg() == 0 && c.IsSet("spec"))) { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } var searchSpec *utils.SpecFiles if c.IsSet("spec") { var err error searchSpec, err = getSearchSpec(c) cliutils.ExitOnErr(err) } else { searchSpec = createDefaultSearchSpec(c) } flags, err := createSearchFlags(c) cliutils.ExitOnErr(err) SearchResult, err := commands.Search(searchSpec, flags) cliutils.ExitOnErr(err) result, err := json.Marshal(SearchResult) cliutils.ExitOnErr(err) fmt.Println(string(cliutils.IndentJson(result))) }
func downloadVersion(c *cli.Context) { if c.NArg() < 1 || c.NArg() > 2 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } versionDetails, err := commands.CreateVersionDetailsForDownloadVersion(c.Args().Get(0)) cliutils.ExitOnErr(err) targetPath := c.Args().Get(1) if strings.HasPrefix(targetPath, "/") { targetPath = targetPath[1:] } flags, err := createDownloadFlags(c) if err != nil { cliutils.Exit(cliutils.ExitCodeError, err.Error()) } downloaded, failed, err := commands.DownloadVersion(versionDetails, targetPath, flags) cliutils.ExitOnErr(err) if failed > 0 { if downloaded > 0 { cliutils.Exit(cliutils.ExitCodeWarning, "") } cliutils.Exit(cliutils.ExitCodeError, "") } }
func configure(c *cli.Context) { if c.NArg() > 1 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } else if c.NArg() == 1 { if c.Args().Get(0) == "show" { commands.ShowConfig() } else if c.Args().Get(0) == "clear" { commands.ClearConfig() } else { cliutils.Exit(cliutils.ExitCodeError, "Unknown argument '"+c.Args().Get(0)+"'. Available arguments are 'show' and 'clear'.") } } else { interactive := cliutils.GetBoolFlagValue(c, "interactive", true) if !interactive { if c.String("user") == "" || c.String("key") == "" { cliutils.Exit(cliutils.ExitCodeError, "The --user and --key options are mandatory when the --interactive option is set to false") } } bintrayDetails, err := createBintrayDetails(c, false) cliutils.ExitOnErr(err) commands.Config(bintrayDetails, nil, interactive) } }
func accessKeys(c *cli.Context) { org := c.String("org") if c.NArg() == 0 { bintrayDetails, err := createBintrayDetails(c, true) cliutils.ExitOnErr(err) err = commands.ShowAccessKeys(bintrayDetails, org) cliutils.ExitOnErr(err) return } if c.NArg() != 2 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } keyId := c.Args().Get(1) var flags *commands.AccessKeyFlags var err error switch c.Args().Get(0) { case "show": flags, err = createAccessKeyFlagsForShowAndDelete(keyId, c) cliutils.ExitOnErr(err) err = commands.ShowAccessKey(flags, org) case "create": flags, err = createAccessKeyFlagsForCreateAndUpdate(keyId, c) cliutils.ExitOnErr(err) err = commands.CreateAccessKey(flags, org) case "update": flags, err = createAccessKeyFlagsForCreateAndUpdate(keyId, c) cliutils.ExitOnErr(err) err = commands.UpdateAccessKey(flags, org) case "delete": flags, err = createAccessKeyFlagsForShowAndDelete(keyId, c) cliutils.ExitOnErr(err) err = commands.DeleteAccessKey(flags, org) default: cliutils.Exit(cliutils.ExitCodeError, "Expecting show, create, update or delete before the key argument. Got "+c.Args().Get(0)) } cliutils.ExitOnErr(err) }
func handleTree(ctx *cli.Context, client *daemon.Client) error { path := "/" if ctx.NArg() > 0 { path = prefixSlash(ctx.Args().First()) } depth := ctx.Int("depth") dirlist, err := client.List(path, depth) if err != nil { return ExitCode{ UnknownError, fmt.Sprintf("ls: %v", err), } } if err := showTree(dirlist, depth); err != nil { return ExitCode{ UnknownError, fmt.Sprintf("Printing tree failed: %v", err), } } return nil }
func beforeCommandRun(ctx *cli.Context) error { if ctx.GlobalIsSet("about") { fmt.Fprintf(os.Stdout, ctx.App.HelpName+"\n\n") fmt.Fprintf(os.Stdout, appCopyright) fmt.Fprintf(os.Stdout, "\n\nThis software is using the following open source components:\n\n") fmt.Fprintf(os.Stdout, "- codegangsta CLI framework\n") fmt.Fprintf(os.Stdout, "\tCopyright (C) 2013 Jeremy Saenz\n") fmt.Fprintf(os.Stdout, "\tAll Rights Reserved.\n") fmt.Fprintf(os.Stdout, "\tMIT license: https://github.com/codegangsta/cli/blob/master/LICENSE\n\n") fmt.Fprintf(os.Stdout, "- ASCII Table Writer\n") fmt.Fprintf(os.Stdout, "\tCopyright (C) 2014 by Oleku Konko\n") fmt.Fprintf(os.Stdout, "\tLicense terms: https://github.com/olekukonko/tablewriter/blob/master/LICENCE.md\n") os.Exit(0) } var err error if ctx.NArg() > 1 { last := ctx.Args()[ctx.NArg()-1] if last != "--help" && last != "-help" && last != "-h" && last != "--h" { api, err = newClient(ctx.GlobalString("apikey"), ctx.GlobalString("baseurl")) } } return err }
func downloadCmd(c *cli.Context) { if c.NArg() > 0 && c.IsSet("spec") { cliutils.Exit(cliutils.ExitCodeError, "No arguments should be sent when the spec option is used. "+cliutils.GetDocumentationMessage()) } if !(c.NArg() == 1 || c.NArg() == 2 || (c.NArg() == 0 && c.IsSet("spec"))) { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } var downloadSpec *utils.SpecFiles if c.IsSet("spec") { var err error downloadSpec, err = getDownloadSpec(c) cliutils.ExitOnErr(err) } else { downloadSpec = createDefaultDownloadSpec(c) } flags, err := createDownloadFlags(c) cliutils.ExitOnErr(err) err = commands.Download(downloadSpec, flags) cliutils.ExitOnErr(err) }
func handleEntitlements(c *cli.Context) { if c.NArg() == 0 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } if c.NArg() == 1 { bintrayDetails, err := createBintrayDetails(c, true) cliutils.ExitOnErr(err) details, err := entitlements.CreateVersionDetails(c.Args().Get(0)) cliutils.ExitOnErr(err) err = entitlements.ShowEntitlements(bintrayDetails, details) cliutils.ExitOnErr(err) return } if c.NArg() != 2 { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } details, err := entitlements.CreateVersionDetails(c.Args().Get(1)) cliutils.ExitOnErr(err) var flags *entitlements.EntitlementFlags switch c.Args().Get(0) { case "show": flags, err = createEntitlementFlagsForShowAndDelete(c) cliutils.ExitOnErr(err) err = entitlements.ShowEntitlement(flags, details) case "create": flags, err = createEntitlementFlagsForCreate(c) cliutils.ExitOnErr(err) err = entitlements.CreateEntitlement(flags, details) case "update": flags, err = createEntitlementFlagsForUpdate(c) cliutils.ExitOnErr(err) err = entitlements.UpdateEntitlement(flags, details) case "delete": flags, err = createEntitlementFlagsForShowAndDelete(c) cliutils.ExitOnErr(err) err = entitlements.DeleteEntitlement(flags, details) default: cliutils.Exit(cliutils.ExitCodeError, "Expecting show, create, update or delete before "+c.Args().Get(1)+". Got "+c.Args().Get(0)) } cliutils.ExitOnErr(err) }
func deleteCmd(c *cli.Context) { if c.NArg() > 0 && c.IsSet("spec") { cliutils.Exit(cliutils.ExitCodeError, "No arguments should be sent when the spec option is used. "+cliutils.GetDocumentationMessage()) } if !(c.NArg() == 1 || (c.NArg() == 0 && c.IsSet("spec"))) { cliutils.Exit(cliutils.ExitCodeError, "Wrong number of arguments. "+cliutils.GetDocumentationMessage()) } var deleteSpec *utils.SpecFiles if c.IsSet("spec") { var err error deleteSpec, err = getDeleteSpec(c) cliutils.ExitOnErr(err) } else { deleteSpec = createDefaultDeleteSpec(c) } flags, err := createDeleteFlags(c) cliutils.ExitOnErr(err) if !c.Bool("quiet") { pathsToDelete, err := commands.GetPathsToDelete(deleteSpec, flags) cliutils.ExitOnErr(err) if len(pathsToDelete) < 1 { return } for _, v := range pathsToDelete { fmt.Println(" " + v.GetFullUrl()) } var confirm string fmt.Print("Are you sure you want to delete the above paths? (y/n): ") fmt.Scanln(&confirm) if !cliutils.ConfirmAnswer(confirm) { return } err = commands.DeleteFiles(pathsToDelete, flags) cliutils.ExitOnErr(err) } else { err = commands.Delete(deleteSpec, flags) cliutils.ExitOnErr(err) } }
func recipes_run(c *cli.Context) error { url := c.GlobalString("url") if url == "" { return cli.NewExitError("A URL must be provided with the SCALE_URL environment variable or the --url argument", 1) } if c.NArg() != 1 && c.NArg() != 2 { return cli.NewExitError("Must specify a single recipe type name or id.", 1) } var recipe_type scalecli.RecipeType found := false id, err := strconv.Atoi(c.Args()[0]) if err == nil { var resp_code int recipe_type, resp_code, err = scalecli.GetRecipeTypeDetails(url, id) if err != nil && resp_code != 404 { return cli.NewExitError(err.Error(), 1) } else if err == nil { found = true } } if !found { name := c.Args()[0] recipe_types, err := scalecli.GetRecipeTypes(url) if err != nil { return cli.NewExitError(err.Error(), 1) } var version string if c.NArg() == 2 { version = c.Args()[1] } switch len(recipe_types) { case 0: return cli.NewExitError("Recipe type not found.", 1) case 1: recipe_type = recipe_types[0] found = true break default: for _, rt := range recipe_types { if rt.Name == name && rt.Version == version { recipe_type = rt found = true break } } if !found { for _, rt := range recipe_types { fmt.Printf("%4d %8s [%25s] - %s\n", rt.Id, rt.Version, rt.Name, rt.Title) } return cli.NewExitError("Multiple recipe types found", 1) } } } data_file := c.String("data") var recipe_data scalecli.RecipeData err = Parse_json_or_yaml(data_file, &recipe_data) if err != nil { return cli.NewExitError(err.Error(), 1) } update_location, err := scalecli.RunRecipe(url, recipe_type.Id, recipe_data) if err != nil { return cli.NewExitError(err.Error(), 1) } color.Blue(fmt.Sprintf("Recipe submited, updates available at %s", update_location)) return nil }
func startReplica(c *cli.Context) error { if c.NArg() != 1 { return errors.New("directory name is required") } dir := c.Args()[0] backingFile, err := openBackingFile(c.String("backing-file")) if err != nil { return err } s := replica.NewServer(dir, backingFile, 512) address := c.String("listen") size := c.String("size") if size != "" { size, err := units.RAMInBytes(size) if err != nil { return err } if err := s.Create(size); err != nil { return err } } controlAddress, dataAddress, syncAddress, err := util.ParseAddresses(address) if err != nil { return err } resp := make(chan error) go func() { server := rest.NewServer(s) router := http.Handler(rest.NewRouter(server)) router = util.FilteredLoggingHandler(map[string]struct{}{ "/ping": struct{}{}, "/v1/replicas/1": struct{}{}, }, os.Stdout, router) logrus.Infof("Listening on control %s", controlAddress) resp <- http.ListenAndServe(controlAddress, router) }() go func() { rpcServer := rpc.New(dataAddress, s) logrus.Infof("Listening on data %s", dataAddress) resp <- rpcServer.ListenAndServe() }() if c.Bool("sync-agent") { exe, err := exec.LookPath(os.Args[0]) if err != nil { return err } exe, err = filepath.Abs(exe) if err != nil { return err } go func() { cmd := exec.Command(exe, "sync-agent", "--listen", syncAddress) cmd.SysProcAttr = &syscall.SysProcAttr{ Pdeathsig: syscall.SIGKILL, } cmd.Dir = dir cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr resp <- cmd.Run() }() } return <-resp }