github.com/defang-io/defang/src@v0.0.0-20240505002154-bdf411911834/cmd/crun/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "os" 8 9 "github.com/defang-io/defang/src/pkg/cmd" 10 "github.com/defang-io/defang/src/pkg/term" 11 "github.com/spf13/pflag" 12 ) 13 14 var ( 15 help = pflag.BoolP("help", "h", false, "Show this help message") 16 region = pflag.StringP("region", "r", os.Getenv("AWS_REGION"), "Which cloud region to use, or blank for local Docker") 17 18 runFlags = pflag.NewFlagSet(os.Args[0]+" run", pflag.ExitOnError) 19 envs = runFlags.StringArrayP("env", "e", nil, "Environment variables to pass to the run command") 20 memory = runFlags.StringP("memory", "m", "2g", "Memory limit in bytes") 21 envFiles = runFlags.StringArray("env-file", nil, "Read in a file of environment variables") 22 platform = runFlags.String("platform", "", "Set platform if host is multi-platform capable") 23 vpcid = runFlags.String("vpcid", "", "VPC to use for the task") 24 subnetid = runFlags.String("subnetid", "", "Subnet to use for the task") 25 // driver = pflag.StringP("driver", "d", "auto", "Container runner to use. Choices are: pulumi-ecs, docker") 26 27 version = "development" // overwritten by build script -ldflags "-X main.version=..." 28 ) 29 30 func init() { 31 runFlags.StringVarP(region, "region", "r", os.Getenv("AWS_REGION"), "Which cloud region to use, or blank for local Docker") 32 } 33 34 func usage() { 35 fmt.Printf("Cloud runner (%s)\n\n", version) 36 fmt.Printf("Usage: \n %s [command] [options]\n\nGlobal Flags:\n", os.Args[0]) 37 pflag.PrintDefaults() 38 fmt.Println(` 39 Commands: 40 run <image> [arg...] Create and run a new task from an image 41 logs <task ID> Fetch the logs of a task 42 stop <task ID> Stop a running task 43 info <task ID> Show information about a task 44 destroy Destroy all resources created by this tool`) 45 fmt.Printf("\n\nUsage of run subcommand: \n %s run [options]\n\nFlags:\n", os.Args[0]) 46 runFlags.PrintDefaults() 47 } 48 49 func main() { 50 pflag.Usage = usage 51 if len(os.Args) < 2 { 52 usage() 53 return 54 } 55 56 command := os.Args[1] 57 58 if command == "run" || command == "r" { 59 runFlags.Parse(os.Args[2:]) 60 } else { 61 pflag.Parse() 62 } 63 64 region := cmd.Region(*region) 65 ctx := context.Background() 66 67 requireTaskID := func() string { 68 if pflag.NArg() != 2 { 69 term.Fatal(command + " requires a single task ID argument") 70 } 71 return pflag.Arg(1) 72 } 73 74 var err error 75 switch command { 76 default: 77 err = errors.New("unknown command: " + command) 78 case "help", "": 79 usage() 80 case "run", "r": 81 if runFlags.NArg() < 1 { 82 term.Fatal("run requires an image name (and optional arguments)") 83 } 84 85 envMap := make(map[string]string) 86 // Apply env vars from files first, so they can be overridden by the command line 87 for _, envFile := range *envFiles { 88 if _, err := cmd.ParseEnvFile(envFile, envMap); err != nil { 89 term.Fatal(err) 90 } 91 } 92 // Apply env vars from the command line last, so they take precedence 93 for _, env := range *envs { 94 if key, value := cmd.ParseEnvLine(env); key != "" { 95 envMap[key] = value 96 } 97 } 98 99 memory := cmd.ParseMemory(*memory) 100 err = cmd.Run(ctx, cmd.RunContainerArgs{ 101 Region: region, 102 Image: runFlags.Arg(0), 103 Memory: memory, 104 Args: runFlags.Args()[1:], 105 Env: envMap, 106 Platform: *platform, 107 VpcID: *vpcid, 108 SubnetID: *subnetid, 109 }) 110 case "stop", "s": 111 taskID := requireTaskID() 112 err = cmd.Stop(ctx, region, &taskID) 113 case "logs", "tail", "l": 114 taskID := requireTaskID() 115 err = cmd.Logs(ctx, region, &taskID) 116 case "destroy", "teardown", "d": 117 if pflag.NArg() != 1 { 118 term.Fatal("destroy does not take any arguments") 119 } 120 err = cmd.Destroy(ctx, region) 121 case "info", "i": 122 taskID := requireTaskID() 123 err = cmd.PrintInfo(ctx, region, &taskID) 124 } 125 126 if err != nil { 127 term.Fatal(err) 128 } 129 }