github.com/defang-io/defang/src@v0.0.0-20240505002154-bdf411911834/pkg/cmd/run.go (about) 1 package cmd 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 "os/signal" 8 "syscall" 9 "time" 10 11 "github.com/defang-io/defang/src/pkg/clouds/aws/ecs/cfn" 12 "github.com/defang-io/defang/src/pkg/types" 13 ) 14 15 type RunContainerArgs struct { 16 Region Region 17 Image string 18 Memory uint64 19 Args []string 20 Env map[string]string 21 Platform string 22 VpcID string 23 SubnetID string 24 } 25 26 var cleanup = make(chan func()) 27 28 func init() { 29 go func() { 30 c := make(chan os.Signal, 1) 31 signal.Notify(c, os.Interrupt, syscall.SIGTERM) 32 var clanupFns []func() 33 34 for { 35 select { 36 case f := <-cleanup: 37 clanupFns = append(clanupFns, f) 38 case s := <-c: 39 fmt.Printf("Caught signal %v, cleaning up...\n", s) 40 for _, f := range clanupFns { 41 f() 42 } 43 os.Exit(0) 44 } 45 } 46 }() 47 } 48 49 func Run(ctx context.Context, args RunContainerArgs) error { 50 driver, err := createDriver(args.Region, cfn.OptionVPCAndSubnetID(ctx, args.VpcID, args.SubnetID)) 51 if err != nil { // VPC affects the cloudformation template 52 return err 53 } 54 55 containers := []types.Container{ 56 { 57 Image: args.Image, 58 Memory: args.Memory, 59 Platform: args.Platform, 60 }, 61 } 62 if err := driver.SetUp(ctx, containers); err != nil { 63 return err 64 } 65 66 id, err := driver.Run(ctx, args.Env, args.Args...) 67 if err != nil { 68 return err 69 } 70 71 cleanup <- func() { 72 fmt.Printf("Stopping task %s...\n", *id) 73 driver.Stop(ctx, id) 74 } 75 fmt.Println("Task ID:", *id) 76 77 // Try 10 times to get the public IP address 78 for i := 0; i < 10; i++ { 79 info, err := driver.GetInfo(ctx, id) 80 if err != nil { 81 time.Sleep(time.Second) 82 continue 83 } 84 if info != nil { 85 fmt.Println("IP:", info.IP) 86 } 87 break 88 } 89 90 // FIXME: stop task on context cancelation/ctrl-c? 91 return driver.Tail(ctx, id) 92 }