Uploading missing files
This commit is contained in:
parent
5c09a0f186
commit
1f4844a1d3
|
@ -0,0 +1,144 @@
|
|||
package dock
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/olekukonko/tablewriter"
|
||||
rfutils "penthertz/rfswift/rfutils"
|
||||
)
|
||||
|
||||
type Tag struct {
|
||||
Name string `json:"name"`
|
||||
Images []Image `json:"images"`
|
||||
TagLastPushed time.Time `json:"tag_last_pushed"`
|
||||
}
|
||||
|
||||
type Image struct {
|
||||
Architecture string `json:"architecture"`
|
||||
Digest string `json:"digest"`
|
||||
}
|
||||
|
||||
type TagList struct {
|
||||
Results []Tag `json:"results"`
|
||||
}
|
||||
|
||||
func getArchitecture() string {
|
||||
switch runtime.GOARCH {
|
||||
case "amd64":
|
||||
return "amd64"
|
||||
case "arm64":
|
||||
return "arm64"
|
||||
case "arm":
|
||||
return "arm"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
func getLatestDockerHubTags(repo string, architecture string) ([]Tag, error) {
|
||||
/*
|
||||
* Get latest Docker images details
|
||||
* in(1): remote repository string
|
||||
* in(2): architecture string
|
||||
* out: tuple status
|
||||
*/
|
||||
url := fmt.Sprintf("https://hub.docker.com/v2/repositories/%s/tags/?page_size=100", repo)
|
||||
|
||||
client := &http.Client{Timeout: 10 * time.Second}
|
||||
resp, err := client.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("failed to get tags: %s", resp.Status)
|
||||
}
|
||||
|
||||
var tagList TagList
|
||||
if err := json.NewDecoder(resp.Body).Decode(&tagList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var filteredTags []Tag
|
||||
for _, tag := range tagList.Results {
|
||||
for _, image := range tag.Images {
|
||||
if image.Architecture == architecture {
|
||||
filteredTags = append(filteredTags, tag)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort tags by pushed date from latest to oldest
|
||||
sort.Slice(filteredTags, func(i, j int) bool {
|
||||
return filteredTags[i].TagLastPushed.After(filteredTags[j].TagLastPushed)
|
||||
})
|
||||
|
||||
// Remove duplicate tags, keeping only the latest
|
||||
uniqueTags := make(map[string]Tag)
|
||||
for _, tag := range filteredTags {
|
||||
if _, exists := uniqueTags[tag.Name]; !exists {
|
||||
uniqueTags[tag.Name] = tag
|
||||
}
|
||||
}
|
||||
|
||||
// Convert map to slice
|
||||
var latestTags []Tag
|
||||
for _, tag := range uniqueTags {
|
||||
latestTags = append(latestTags, tag)
|
||||
}
|
||||
|
||||
// Sort the tags again to ensure they are in the correct order after deduplication
|
||||
sort.Slice(latestTags, func(i, j int) bool {
|
||||
return latestTags[i].TagLastPushed.After(latestTags[j].TagLastPushed)
|
||||
})
|
||||
|
||||
return latestTags, nil
|
||||
}
|
||||
|
||||
func ListDockerImagesRepo() {
|
||||
/*
|
||||
* Prints Latest tags for RF Swift
|
||||
*/
|
||||
repo := "penthertz/rfswift" // Change this to the repository you want to check
|
||||
architecture := getArchitecture()
|
||||
|
||||
if architecture == "" {
|
||||
log.Fatalf("Unsupported architecture: %s", runtime.GOARCH)
|
||||
}
|
||||
|
||||
tags, err := getLatestDockerHubTags(repo, architecture)
|
||||
if err != nil {
|
||||
log.Fatalf("Error getting tags: %v", err)
|
||||
}
|
||||
|
||||
rfutils.ClearScreen()
|
||||
|
||||
table := tablewriter.NewWriter(os.Stdout)
|
||||
table.SetHeader([]string{"Tag", "Pushed Date", "Image", "Architecture", "Digest"})
|
||||
|
||||
for _, tag := range tags {
|
||||
for _, image := range tag.Images {
|
||||
if image.Architecture == architecture {
|
||||
table.Append([]string{
|
||||
tag.Name,
|
||||
tag.TagLastPushed.Format(time.RFC3339),
|
||||
fmt.Sprintf("%s:%s", repo, tag.Name),
|
||||
image.Architecture,
|
||||
image.Digest,
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table.Render()
|
||||
}
|
|
@ -0,0 +1,227 @@
|
|||
package rfutils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/cheggaaa/pb/v3"
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
type Release struct {
|
||||
TagName string `json:"tag_name"`
|
||||
}
|
||||
|
||||
func getLatestRelease(owner string, repo string) (Release, error) {
|
||||
/*
|
||||
* Get Latest Release information
|
||||
* in(1): owner string
|
||||
* in(2): repository string
|
||||
* out: status
|
||||
*/
|
||||
client := resty.New()
|
||||
|
||||
resp, err := client.R().
|
||||
SetHeader("Accept", "application/vnd.github.v3+json").
|
||||
Get(fmt.Sprintf("https://api.github.com/repos/%s/%s/releases/latest", owner, repo))
|
||||
|
||||
if err != nil {
|
||||
return Release{}, err
|
||||
}
|
||||
|
||||
if resp.StatusCode() != http.StatusOK {
|
||||
return Release{}, fmt.Errorf("failed to get latest release: %s", resp.Status())
|
||||
}
|
||||
|
||||
var release Release
|
||||
if err := json.Unmarshal(resp.Body(), &release); err != nil {
|
||||
return Release{}, err
|
||||
}
|
||||
|
||||
return release, nil
|
||||
}
|
||||
|
||||
func constructDownloadURL(owner, repo, tag, fileName string) string {
|
||||
/*
|
||||
* Construct download URL link for RF Swift release
|
||||
* in(1): owner string
|
||||
* in(2): repository string
|
||||
* in(3): tag string
|
||||
* in(4): filename string
|
||||
* out: status
|
||||
*/
|
||||
return fmt.Sprintf("https://github.com/%s/%s/releases/download/%s/%s", owner, repo, tag, fileName)
|
||||
}
|
||||
|
||||
func downloadFile(url, dest string) error {
|
||||
/*
|
||||
* Download RF swift binary realse
|
||||
* in(1): string url
|
||||
* in(2): destinarion string
|
||||
* out: status
|
||||
*/
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("failed to download file: %s", resp.Status)
|
||||
}
|
||||
|
||||
size, err := strconv.Atoi(resp.Header.Get("Content-Length"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out, err := os.Create(dest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
bar := pb.Full.Start64(int64(size))
|
||||
barReader := bar.NewProxyReader(resp.Body)
|
||||
_, err = io.Copy(out, barReader)
|
||||
bar.Finish()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func makeExecutable(path string) error {
|
||||
/*
|
||||
* Making downloaded RF Swift binary executable
|
||||
* in(1): string path
|
||||
* out: status
|
||||
*/
|
||||
err := os.Chmod(path, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func replaceBinary(newBinaryPath, binaryName string) error {
|
||||
/*
|
||||
* Replace original RF Swift binary by the latest release
|
||||
* in(1): latest binary string
|
||||
* in(2): original binary string
|
||||
* out: status
|
||||
*/
|
||||
// Ensure the new binary is executable
|
||||
err := makeExecutable(newBinaryPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Determine the current binary path
|
||||
currentBinaryPath, err := exec.LookPath(binaryName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Replace the current binary with the new one
|
||||
err = os.Rename(newBinaryPath, currentBinaryPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetLatestRFSwift() {
|
||||
/*
|
||||
* Print latest RF Swift binary from official Penthertz' repository
|
||||
*/
|
||||
owner := "PentHertz"
|
||||
repo := "RF-Swift"
|
||||
|
||||
release, err := getLatestRelease(owner, repo)
|
||||
if err != nil {
|
||||
log.Fatalf("Error getting latest release: %v", err)
|
||||
}
|
||||
|
||||
arch := runtime.GOARCH
|
||||
goos := runtime.GOOS
|
||||
|
||||
var fileName string
|
||||
|
||||
switch goos {
|
||||
case "linux":
|
||||
switch arch {
|
||||
case "amd64":
|
||||
fileName = "rfswift_linux_amd64"
|
||||
case "arm64":
|
||||
fileName = "rfswift_linux_arm64"
|
||||
default:
|
||||
log.Fatalf("Unsupported architecture: %s", arch)
|
||||
}
|
||||
case "windows":
|
||||
switch arch {
|
||||
case "amd64":
|
||||
fileName = "rfswift_windows_amd64.exe"
|
||||
case "arm64":
|
||||
fileName = "rfswift_windows_arm64.exe"
|
||||
default:
|
||||
log.Fatalf("Unsupported architecture: %s", arch)
|
||||
}
|
||||
default:
|
||||
log.Fatalf("Unsupported operating system: %s", goos)
|
||||
}
|
||||
|
||||
downloadURL := constructDownloadURL(owner, repo, release.TagName, fileName)
|
||||
fmt.Printf("Latest release download URL: %s\n", downloadURL)
|
||||
|
||||
fmt.Printf("Do you want to replace the existing 'rfswift' binary with this new release? (yes/no): ")
|
||||
var response string
|
||||
fmt.Scanln(&response)
|
||||
|
||||
if response == "yes" {
|
||||
tempDest := filepath.Join(os.TempDir(), fileName)
|
||||
err = downloadFile(downloadURL, tempDest)
|
||||
if err != nil {
|
||||
log.Fatalf("Error downloading file: %v", err)
|
||||
}
|
||||
|
||||
err = replaceBinary(tempDest, "./rfswift")
|
||||
if err != nil {
|
||||
log.Fatalf("Error replacing binary: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println("File downloaded and replaced successfully.")
|
||||
} else {
|
||||
// Get the current binary directory
|
||||
currentBinaryPath, err := exec.LookPath("./rfswift")
|
||||
if err != nil {
|
||||
log.Fatalf("Error locating current binary: %v", err)
|
||||
}
|
||||
|
||||
var dest string
|
||||
ext := filepath.Ext(fileName)
|
||||
name := strings.TrimSuffix(fileName, ext)
|
||||
dest = filepath.Join(filepath.Dir(currentBinaryPath), fmt.Sprintf("%s_%s%s", name, release.TagName, ext))
|
||||
|
||||
err = downloadFile(downloadURL, dest)
|
||||
if err != nil {
|
||||
log.Fatalf("Error downloading file: %v", err)
|
||||
}
|
||||
|
||||
// Make the new binary executable
|
||||
err = makeExecutable(dest)
|
||||
if err != nil {
|
||||
log.Fatalf("Error making binary executable: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("File downloaded and saved at %s\n", dest)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue