Uploading missing files

This commit is contained in:
FlUxIuS 2024-07-14 17:31:23 +02:00
parent 5c09a0f186
commit 1f4844a1d3
No known key found for this signature in database
GPG Key ID: E8B96449EE4FA72F
2 changed files with 371 additions and 0 deletions

View File

@ -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()
}

View File

@ -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)
}
}