github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/ksync/cli.go (about)

     1  package ksync
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"runtime"
     8  	"strings"
     9  
    10  	"github.com/olli-ai/jx/v2/pkg/packages"
    11  	"github.com/olli-ai/jx/v2/pkg/util"
    12  )
    13  
    14  var commit string
    15  var binary = "ksync"
    16  
    17  // CLI implements the command ksync commands contained in KSyncer.
    18  type CLI struct {
    19  	Runner util.Commander
    20  }
    21  
    22  // NewCLI creates a new KsyncCLI instance configured to use the provided ksync CLI in the given current working directory
    23  func NewCLI() (*CLI, error) {
    24  	path, err := util.JXBinLocation()
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  	runner := &util.Command{
    29  		Name: fmt.Sprintf("%s/ksync", path),
    30  	}
    31  	cli := &CLI{
    32  		Runner: runner,
    33  	}
    34  	return cli, nil
    35  }
    36  
    37  // isInstalled checks if the binary is installed
    38  func isInstalled(binary string) (bool, error) {
    39  	flag, err := packages.ShouldInstallBinary(binary)
    40  	return flag, err
    41  }
    42  
    43  // getTag returns the latest full tag from github given the owner and repo, and installs
    44  func getTag(owner, repo string) (string, string, error) {
    45  	latestTag, err := util.GetLatestFullTagFromGithub(owner, repo)
    46  	if err != nil {
    47  		return "", "", err
    48  	}
    49  	latestVersion := *latestTag.Name
    50  	// This will return the shortsha, the first 7 characters associated with the git commit
    51  	latestSha := (*latestTag.Commit.SHA)[:7]
    52  	return latestSha, latestVersion, nil
    53  }
    54  
    55  // install downloads and installs the ksync package
    56  func install(latestVersion, binDir, fileName string) error {
    57  	clientURL := fmt.Sprintf("https://github.com/ksync/ksync/releases/download/%s/ksync_%s_%s", latestVersion, runtime.GOOS, runtime.GOARCH)
    58  	if runtime.GOOS == "windows" {
    59  		clientURL += ".exe"
    60  	}
    61  	fullPath := filepath.Join(binDir, fileName)
    62  	tmpFile := fullPath + ".tmp"
    63  	err := packages.DownloadFile(clientURL, tmpFile)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	err = util.RenameFile(tmpFile, fullPath)
    68  	if err != nil {
    69  		return err
    70  	}
    71  	err = os.Chmod(fullPath, 0755)
    72  	if err != nil {
    73  		return err
    74  	}
    75  	return nil
    76  }
    77  
    78  // Version prints out the version of the local component of ksync
    79  func (kcli *CLI) Version() (string, error) {
    80  	args := []string{"version"}
    81  	kcli.Runner.SetArgs(args)
    82  	out, _ := kcli.Runner.RunWithoutRetry()
    83  	return out, nil
    84  }
    85  
    86  // Init installs the server side component of ksync - the daemonsets
    87  func (kcli *CLI) Init(flags ...string) (string, error) {
    88  	args := []string{"init"}
    89  	args = append(args, flags...)
    90  	kcli.Runner.SetArgs(args)
    91  	out, err := kcli.Runner.RunWithoutRetry()
    92  	if err != nil {
    93  		return "", err
    94  	}
    95  	return out, nil
    96  }
    97  
    98  // Clean removes the ksync pods
    99  func (kcli *CLI) Clean() (string, error) {
   100  	args := []string{"clean"}
   101  	kcli.Runner.SetArgs(args)
   102  	out, err := kcli.Runner.RunWithoutRetry()
   103  	if err != nil {
   104  		return "", err
   105  	}
   106  	return out, nil
   107  }
   108  
   109  // InstallKSync installs ksync, it returns the sha of the latest commit
   110  func InstallKSync() (string, error) {
   111  	binDir, err := util.JXBinLocation()
   112  	if err != nil {
   113  		return "", err
   114  	}
   115  
   116  	download, err := isInstalled(binary)
   117  	if err != nil || !download {
   118  		// Exec `ksync` to find the version
   119  
   120  		kcli, err := NewCLI()
   121  		if err != nil {
   122  			return "", err
   123  		}
   124  		res, err := kcli.Version()
   125  		if err != nil {
   126  			return "", err
   127  		}
   128  
   129  		commit = getCommitShaFromVersion(res)
   130  		if commit != "" {
   131  			return commit, nil
   132  		}
   133  		return "", fmt.Errorf("unable to find version of ksync")
   134  	}
   135  	latestSha, latestVersion, err := getTag("ksync", "ksync")
   136  	if err != nil {
   137  		return "", err
   138  	}
   139  
   140  	err = install(latestVersion, binDir, packages.BinaryWithExtension(binary))
   141  	if err != nil {
   142  		return "", err
   143  	}
   144  
   145  	return latestSha, nil
   146  }
   147  
   148  func getCommitShaFromVersion(result string) string {
   149  	lines := strings.Split(result, "\n")
   150  	for _, line := range lines {
   151  		line = strings.TrimSpace(line)
   152  		if strings.HasPrefix(line, "Git Commit:") {
   153  			commit = strings.TrimSpace(strings.TrimPrefix(line, "Git Commit:"))
   154  		}
   155  	}
   156  	return commit
   157  }