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  }