github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/client/cli/run/util.go (about)

     1  package runtime
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"os/exec"
     9  	"path/filepath"
    10  
    11  	pb "github.com/tickoalcantara12/micro/v3/proto/runtime"
    12  	"github.com/tickoalcantara12/micro/v3/service/build/util/tar"
    13  	"github.com/tickoalcantara12/micro/v3/service/client"
    14  	"github.com/tickoalcantara12/micro/v3/service/context"
    15  	"github.com/tickoalcantara12/micro/v3/service/runtime"
    16  	"github.com/tickoalcantara12/micro/v3/service/runtime/source/git"
    17  	"github.com/urfave/cli/v2"
    18  )
    19  
    20  const bufferSize = 1024
    21  
    22  // upload source to the server. will return the source id, e.g. source://foo-bar and an error if
    23  // one occurred. The ID returned can be used as a source in runtime.Create.
    24  func upload(ctx *cli.Context, srv *runtime.Service, source *git.Source) (string, error) {
    25  	// if the source exists within a local git repository, archive the whole repository, otherwise
    26  	// just archive the folder
    27  	var data io.Reader
    28  	var err error
    29  	if len(source.LocalRepoRoot) > 0 {
    30  		data, err = tar.Archive(source.LocalRepoRoot)
    31  	} else {
    32  		data, err = tar.Archive(source.FullPath)
    33  	}
    34  	if err != nil {
    35  		return "", err
    36  	}
    37  
    38  	// create an upload stream
    39  	cli := pb.NewSourceService("runtime", client.DefaultClient)
    40  	stream, err := cli.Upload(context.DefaultContext, client.WithAuthToken())
    41  	if err != nil {
    42  		return "", err
    43  	}
    44  
    45  	// read bytes from the tar and stream it to the server
    46  	buffer := make([]byte, bufferSize)
    47  	var sentService bool
    48  	for {
    49  		num, err := data.Read(buffer)
    50  		if err == io.EOF {
    51  			break
    52  		} else if err != nil {
    53  			return "", err
    54  		}
    55  
    56  		req := &pb.UploadRequest{Data: buffer[:num]}
    57  
    58  		// construct the service object, we'll send this on the first message only to reduce the amount of
    59  		// data needed to be streamed
    60  		if !sentService {
    61  			req.Service = &pb.Service{Name: srv.Name, Version: srv.Version}
    62  			sentService = true
    63  		}
    64  
    65  		if err := stream.Send(req); err != nil {
    66  			return "", err
    67  		}
    68  	}
    69  
    70  	// wait for the server to process the source
    71  	rsp, err := stream.CloseAndRecv()
    72  	if err != nil {
    73  		return "", err
    74  	}
    75  	return rsp.Id, nil
    76  }
    77  
    78  // vendorDependencies will use `go mod vendor` to generate a vendor directory containing all of a
    79  // services deps. This is then uploaded to the server along with the source code to be built into
    80  // a binary.
    81  func vendorDependencies(dir string) error {
    82  	// find the go command
    83  	gopath, err := locateGo()
    84  	if err != nil {
    85  		return err
    86  	}
    87  
    88  	// construct the command
    89  	cmd := exec.Command(gopath, "mod", "vendor")
    90  	cmd.Env = append(os.Environ(), "GO111MODULE=auto")
    91  	cmd.Dir = dir
    92  
    93  	// execute the command and get the error output
    94  	outp := bytes.NewBuffer(nil)
    95  	cmd.Stderr = outp
    96  	if err := cmd.Run(); err != nil {
    97  		return fmt.Errorf("%v: %v", err, outp.String())
    98  	}
    99  
   100  	return nil
   101  }
   102  
   103  // locateGo locates the go command
   104  func locateGo() (string, error) {
   105  	if gr := os.Getenv("GOROOT"); len(gr) > 0 {
   106  		return filepath.Join(gr, "bin", "go"), nil
   107  	}
   108  
   109  	// check path
   110  	for _, p := range filepath.SplitList(os.Getenv("PATH")) {
   111  		bin := filepath.Join(p, "go")
   112  		if _, err := os.Stat(bin); err == nil {
   113  			return bin, nil
   114  		}
   115  	}
   116  
   117  	return exec.LookPath("go")
   118  }