Develop #3

Merged
metal3d merged 18 commits from develop into master 2022-03-31 12:12:20 +00:00
3 changed files with 216 additions and 4 deletions
Showing only changes of commit ce46b848dd - Show all commits

57
main.go
View File

@@ -1,9 +1,11 @@
package main
import (
"fmt"
"katenary/cmd"
"katenary/generator/writers"
"katenary/helm"
"katenary/update"
"strconv"
"github.com/spf13/cobra"
@@ -92,10 +94,57 @@ func main() {
},
}
rootCmd.AddCommand(versionCmd)
rootCmd.AddCommand(convertCmd)
rootCmd.AddCommand(showLabelsCmd)
// Update the binary to the latest version
updateCmd := &cobra.Command{
Use: "upgrade",
Short: "Upgrade katenary to the latest version if available",
Run: func(c *cobra.Command, args []string) {
version, assets, err := update.CheckLatestVersion()
if err != nil {
c.Println(err)
return
}
c.Println("Updating to version: " + version)
err = update.DownloadLatestVersion(assets)
if err != nil {
c.Println(err)
return
}
c.Println("Update completed")
},
}
rootCmd.Execute()
rootCmd.AddCommand(
versionCmd,
convertCmd,
showLabelsCmd,
updateCmd,
)
// in parallel, check if the current katenary version is the latest
ch := make(chan string)
go func() {
version, _, err := update.CheckLatestVersion()
if err != nil {
ch <- ""
return
}
if cmd.Version != version {
ch <- fmt.Sprintf("\x1b[33mNew version available: " +
version +
" - to auto upgrade katenary, you can execute: katenary upgrade\x1b[0m\n")
}
}()
// Execute the command
finalize := make(chan error)
go func() {
finalize <- rootCmd.Execute()
}()
// Wait for both goroutines to finish
if err := <-finalize; err != nil {
fmt.Println(err)
}
fmt.Print(<-ch)
}

127
update/main.go Normal file
View File

@@ -0,0 +1,127 @@
package update
import (
"encoding/json"
"errors"
"fmt"
"io"
"katenary/cmd"
"net/http"
"os"
"runtime"
"time"
)
var exe, _ = os.Executable()
// Asset is a github asset from release url.
type Asset struct {
Name string `json:"name"`
URL string `json:"browser_download_url"`
}
// CheckLatestVersion check katenary latest version from release and propose to download it
func CheckLatestVersion() (string, []Asset, error) {
githuburl := "https://api.github.com/repos/metal3d/katenary/releases/latest"
// Create a HTTP client with 1s timeout
client := &http.Client{
Timeout: time.Second * 1,
}
// Create a request
req, err := http.NewRequest("GET", githuburl, nil)
if err != nil {
return "", nil, err
}
// Send the request via a client
resp, err := client.Do(req)
if err != nil {
return "", nil, err
}
defer resp.Body.Close()
// Get tag_name from the json response
var release = struct {
TagName string `json:"tag_name"`
Assets []Asset `json:"assets"`
}{}
err = json.NewDecoder(resp.Body).Decode(&release)
if err != nil {
return "", nil, err
}
if release.TagName == "" {
return "", nil, errors.New("No release found")
}
if cmd.Version == release.TagName {
fmt.Println("You are using the latest version")
return "", nil, errors.New("You are using the latest version")
}
return release.TagName, release.Assets, nil
}
func DownloadLatestVersion(assets []Asset) error {
// Download the latest version
fmt.Println("Downloading the latest version...")
// ok, replace this from the current version to the latest version
err := os.Rename(exe, exe+".old")
if err != nil {
return err
}
// Download the latest version for the current OS
for _, asset := range assets {
switch runtime.GOOS {
case "windows":
if asset.Name == "katenary.exe" {
err = DownloadFile(asset.URL, exe)
}
case "linux":
switch runtime.GOARCH {
case "amd64":
if asset.Name == "katenary-linux-amd64" {
err = DownloadFile(asset.URL, exe)
}
case "arm64":
if asset.Name == "katenary-linux-arm64" {
err = DownloadFile(asset.URL, exe)
}
}
case "darwin":
if asset.Name == "katenary-darwin" {
err = DownloadFile(asset.URL, exe)
}
default:
fmt.Println("Unsupported OS")
err = errors.New("Unsupported OS")
}
}
if err == nil {
// remove the old version
os.Remove(exe + ".old")
} else {
// restore the old version
os.Rename(exe+".old", exe)
}
return err
}
func DownloadFile(url, exe string) error {
// Download the url binary to exe path
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
fp, err := os.OpenFile(exe, os.O_WRONLY|os.O_CREATE, 0755)
if err != nil {
return err
}
defer fp.Close()
_, err = io.Copy(fp, resp.Body)
return err
}

36
update/update_test.go Normal file
View File

@@ -0,0 +1,36 @@
package update
import (
"fmt"
"katenary/cmd"
"os"
"testing"
)
func TestDownloadLatestRelease(t *testing.T) {
// Change the cmd.Version to "v0.0.0" to test the fallback to the latest release
cmd.Version = "v0.0.0"
// change "exe" to /tmp/test-katenary
exe = "/tmp/test-katenary"
// Now call the CheckLatestVersion function
version, assets, err := CheckLatestVersion()
if err != nil {
t.Errorf("Error: %s", err)
}
fmt.Println("Version found", version)
// Touch exe binary
f, _ := os.OpenFile(exe, os.O_RDONLY|os.O_CREATE, 0755)
f.Write(nil)
f.Close()
err = DownloadLatestVersion(assets)
if err != nil {
t.Errorf("Error: %s", err)
}
}