version.go RawHistoryFolder
1package common
2
3import (
4 "encoding/json"
5 "fmt"
6 "io"
7 "log"
8 "net/http"
9 "runtime"
10 "time"
11
12 "github.com/bnema/gordon/pkg/docker"
13)
14
15type CurrentVersion struct {
16 isContainer bool
17 Version string `json:"version"`
18}
19
20type ArchVersion struct {
21 Name string `json:"name"`
22}
23
24type VersionInfo struct {
25 Name string `json:"name"`
26}
27
28type VersionsResponse struct {
29 AMD64 string `json:"amd64"`
30 ARM64 string `json:"arm64"`
31}
32
33func GetCurrentBuildVersionInfo(c *Config) CurrentVersion {
34 return CurrentVersion{
35 isContainer: docker.IsRunningInContainer(),
36 Version: c.GetVersion(),
37 }
38}
39
40func CheckForNewVersion(localVersion, remoteVersion string) string {
41 if localVersion != remoteVersion {
42 return "A new version is available"
43 }
44 return ""
45}
46
47func getArch() string {
48 return runtime.GOARCH
49}
50
51func checkAndUpdateVersion(c *Config) (string, error) {
52 localVersion := GetCurrentBuildVersionInfo(c)
53 remoteVersions, err := getRemoteVersion(c)
54 if err != nil {
55 return "", err
56 }
57
58 var remoteVersion string
59 switch getArch() {
60 case "amd64":
61 remoteVersion = remoteVersions.AMD64
62 case "arm64":
63 remoteVersion = remoteVersions.ARM64
64 default:
65 return "", fmt.Errorf("unsupported architecture: %s", getArch())
66 }
67
68 // Check if remoteVersion is empty
69 if remoteVersion == "" {
70 return "", fmt.Errorf("remote version not available for architecture %s", getArch())
71 }
72
73 message := CheckForNewVersion(localVersion.Version, remoteVersion)
74
75 // Return the message without an error, even if it's empty
76 return message, nil
77}
78
79func CheckVersionPeriodically(c *Config) (string, error) {
80 // Perform an immediate check.
81 newVersionMessage, err := checkAndUpdateVersion(c)
82
83 if err != nil {
84 return "", err
85 }
86
87 if newVersionMessage != "" {
88 fmt.Println(newVersionMessage)
89 return "", nil
90 }
91
92 // Set up a ticker to check every 5 minutes.
93 timer := time.NewTicker(5 * time.Minute)
94 defer timer.Stop()
95
96 for range timer.C {
97 newVersionMessage, err = checkAndUpdateVersion(c)
98 if err != nil {
99 log.Printf("Error fetching remote version: %s", err)
100 continue
101 }
102
103 if newVersionMessage != "" {
104 fmt.Println(newVersionMessage)
105 return "", nil //We return so the loop stops in case of a new version
106 }
107 }
108
109 return "", nil
110}
111
112func getRemoteVersion(c *Config) (VersionsResponse, error) {
113 proxyURL := c.Build.ProxyURL
114 if proxyURL == "" {
115 return VersionsResponse{}, fmt.Errorf("proxy URL is empty")
116 }
117
118 checkVersionEndpoint := proxyURL + "/version"
119 resp, err := http.Get(checkVersionEndpoint)
120 if err != nil {
121 return VersionsResponse{}, err
122 }
123
124 defer resp.Body.Close()
125
126 body, err := io.ReadAll(resp.Body)
127 if err != nil {
128 return VersionsResponse{}, err
129 }
130
131 var remoteVersionInfo VersionsResponse
132 err = json.Unmarshal(body, &remoteVersionInfo)
133 if err != nil {
134 return VersionsResponse{}, err
135 }
136
137 return remoteVersionInfo, nil
138}