github.com/serge-v/zero@v1.0.2-0.20220911142406-af4b6a19e68a/zero.go (about)

     1  package zero
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"log"
     7  	"net/http"
     8  	"os"
     9  	"os/exec"
    10  	"path/filepath"
    11  	"time"
    12  )
    13  
    14  var durl = "https://zero.voilokov.com/"
    15  
    16  // Deploy installs and starts golang app from the current directory to the zero server.
    17  func Deploy(port int) error {
    18  	fname, err := buildApp()
    19  	if err != nil {
    20  		return fmt.Errorf("build: %w", err)
    21  	}
    22  	appname := filepath.Base(fname)
    23  
    24  	f, err := os.Open(fname)
    25  	if err != nil {
    26  		return fmt.Errorf("open: %w", err)
    27  	}
    28  	defer f.Close()
    29  
    30  	token, err := getToken()
    31  	if err != nil {
    32  		return fmt.Errorf("read token: %w", err)
    33  	}
    34  
    35  	params := fmt.Sprintf("deploy?appname=%s&token=%s&port=%d", appname, token, port)
    36  	resp, err := http.Post(durl+params, "application/octet-stream", f)
    37  	if err != nil {
    38  		return fmt.Errorf("post to %s: %w", durl, err)
    39  	}
    40  	defer resp.Body.Close()
    41  
    42  	buf, err := ioutil.ReadAll(resp.Body)
    43  	if err != nil {
    44  		return fmt.Errorf("read all: %w", err)
    45  	}
    46  
    47  	if resp.StatusCode != http.StatusOK {
    48  		return fmt.Errorf("status: %s, resp:\n%s\n", resp.Status, string(buf))
    49  	}
    50  
    51  	return nil
    52  }
    53  
    54  // Log gets an app log from the zero server.
    55  func Log() (string, error) {
    56  	dir, err := os.Getwd()
    57  	if err != nil {
    58  		return "", fmt.Errorf("cwd: %w", err)
    59  	}
    60  
    61  	appname := filepath.Base(dir)
    62  	token, err := getToken()
    63  	if err != nil {
    64  		return "", fmt.Errorf("read token: %w", err)
    65  	}
    66  
    67  	params := fmt.Sprintf("log?appname=%s&token=%s", appname, token)
    68  	resp, err := http.Get(durl + params)
    69  	if err != nil {
    70  		return "", fmt.Errorf("post to %s: %w", durl, err)
    71  	}
    72  	defer resp.Body.Close()
    73  
    74  	buf, err := ioutil.ReadAll(resp.Body)
    75  	if err != nil {
    76  		return "", fmt.Errorf("read all: %w", err)
    77  	}
    78  
    79  	if resp.StatusCode != http.StatusOK {
    80  		return "", fmt.Errorf("status: %s, resp:\n%s\n", resp.Status, string(buf))
    81  	}
    82  
    83  	return string(buf), nil
    84  }
    85  
    86  func getToken() (string, error) {
    87  	buf, err := ioutil.ReadFile("token~.txt")
    88  	if err != nil {
    89  		return "", fmt.Errorf("read token: %w", err)
    90  	}
    91  	return string(buf), nil
    92  }
    93  
    94  func buildApp() (string, error) {
    95  	dir, err := os.Getwd()
    96  	if err != nil {
    97  		return "", fmt.Errorf("cwd: %w", err)
    98  	}
    99  
   100  	appname := filepath.Base(dir)
   101  	outdir, err := ioutil.TempDir("", "zero-*")
   102  	if err != nil {
   103  		return "", fmt.Errorf("temp dir: %w", err)
   104  	}
   105  
   106  	outname := filepath.Join(outdir, appname)
   107  
   108  	cmd := exec.Command("go", "build", "-ldflags", "-X main.compileDate="+time.Now().Format("2006-01-02T15:04:05-MST"), "-o", outname)
   109  	cmd.Env = os.Environ()
   110  	cmd.Env = append(cmd.Env, "GOOS=linux", "GOARCH=amd64")
   111  	log.Println("building:", dir, cmd.Args)
   112  
   113  	buf, err := cmd.CombinedOutput()
   114  	log.Println(string(buf))
   115  	if err != nil {
   116  		return string(buf), fmt.Errorf("run compiler: %w", err)
   117  	}
   118  	log.Println("built:", outname)
   119  	return outname, nil
   120  }