Testfeature new version notification
- commit
- 38e97fbb47ab6add5cc58f5a6716647f5a4724d9
- author
- bnema · · 2023-11-03 16:23 UTC
- parent
- 2f5e3b7
- signature
- unsigned
6 files · +227 -13
A .vscode/launch.json +18 -0
| @@ -0,0 +1,18 @@ | |||
| 1 | + | { | |
| 2 | + | // Utilisez IntelliSense pour en savoir plus sur les attributs possibles. | |
| 3 | + | // Pointez pour afficher la description des attributs existants. | |
| 4 | + | // Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387 | |
| 5 | + | "version": "0.2.0", | |
| 6 | + | "configurations": [ | |
| 7 | + | { | |
| 8 | + | "name": "Launch file", | |
| 9 | + | "type": "go", | |
| 10 | + | "request": "launch", | |
| 11 | + | "mode": "debug", | |
| 12 | + | "program": "./cmd/cli/main.go", | |
| 13 | + | } | |
| 14 | + | ||
| 15 | + | ||
| 16 | + | ] | |
| 17 | + | ||
| 18 | + | }⏎̸ | |
| @@ -0,0 +1,18 @@ | |||||
| 1 | + | { | |||
| 2 | + | // Utilisez IntelliSense pour en savoir plus sur les attributs possibles. | |||
| 3 | + | // Pointez pour afficher la description des attributs existants. | |||
| 4 | + | // Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387 | |||
| 5 | + | "version": "0.2.0", | |||
| 6 | + | "configurations": [ | |||
| 7 | + | { | |||
| 8 | + | "name": "Launch file", | |||
| 9 | + | "type": "go", | |||
| 10 | + | "request": "launch", | |||
| 11 | + | "mode": "debug", | |||
| 12 | + | "program": "./cmd/cli/main.go", | |||
| 13 | + | } | |||
| 14 | + | ||||
| 15 | + | ||||
| 16 | + | ] | |||
| 17 | + | ||||
| 18 | + | }⏎̸ | |||
M cmd/cli/main.go +32 -5
| @@ -2,16 +2,22 @@ package main | |||
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | 4 | "fmt" | |
| 5 | + | "log" | |
| 5 | 6 | "regexp" | |
| 6 | 7 | ||
| 7 | 8 | "github.com/bnema/gordon/internal/cli" | |
| 8 | 9 | "github.com/bnema/gordon/internal/cli/cmd" | |
| 9 | 10 | "github.com/bnema/gordon/internal/common" | |
| 10 | 11 | "github.com/bnema/gordon/internal/server" | |
| 12 | + | "github.com/bnema/gordon/pkg/docker" | |
| 11 | 13 | "github.com/spf13/cobra" | |
| 12 | 14 | ) | |
| 13 | 15 | ||
| 14 | - | var build string | |
| 16 | + | var ( | |
| 17 | + | build string | |
| 18 | + | commit string | |
| 19 | + | date string | |
| 20 | + | ) | |
| 15 | 21 | ||
| 16 | 22 | var rootCmd = &cobra.Command{Use: "gordon"} | |
| 17 | 23 | ||
| @@ -38,11 +44,32 @@ func main() { | |||
| 38 | 44 | ||
| 39 | 45 | common.DockerInit(&s.Config.ContainerEngine) | |
| 40 | 46 | ||
| 41 | - | // build looks like this: "0.0.901-b98a337" | |
| 42 | - | //use regex to only get the version number | |
| 43 | 47 | build = regexp.MustCompile(`\d+\.\d+\.\d+`).FindString(build) | |
| 44 | - | // Set the BuildVersion | |
| 45 | - | s.Config.Build.BuildVersion = build | |
| 48 | + | s.Config.Build = common.BuildConfig{ | |
| 49 | + | BuildVersion: build, | |
| 50 | + | BuildCommit: commit, | |
| 51 | + | BuildDate: date, | |
| 52 | + | ProxyURL: "https://gordon-proxy.bnema.dev", | |
| 53 | + | } | |
| 54 | + | ||
| 55 | + | digest, err := docker.WhoAmI() | |
| 56 | + | if err != nil { | |
| 57 | + | log.Println(err) | |
| 58 | + | } | |
| 59 | + | ||
| 60 | + | fmt.Printf("Gordon version %s (%s) built on %s\n", s.Config.Build.BuildVersion, digest, s.Config.Build.BuildDate) | |
| 61 | + | ||
| 62 | + | go func() { | |
| 63 | + | msg, err := common.CheckVersionPeriodically(&s.Config) | |
| 64 | + | if err != nil { | |
| 65 | + | log.Println(err) | |
| 66 | + | } | |
| 67 | + | ||
| 68 | + | if msg != "" { | |
| 69 | + | log.Println(msg) | |
| 70 | + | } | |
| 71 | + | ||
| 72 | + | }() | |
| 46 | 73 | ||
| 47 | 74 | Execute(a, s) | |
| 48 | 75 | } | |
| @@ -2,16 +2,22 @@ package main | |||||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | "fmt" | 4 | "fmt" | ||
| 5 | + | "log" | |||
| 5 | "regexp" | 6 | "regexp" | ||
| 6 | 7 | ||||
| 7 | "github.com/bnema/gordon/internal/cli" | 8 | "github.com/bnema/gordon/internal/cli" | ||
| 8 | "github.com/bnema/gordon/internal/cli/cmd" | 9 | "github.com/bnema/gordon/internal/cli/cmd" | ||
| 9 | "github.com/bnema/gordon/internal/common" | 10 | "github.com/bnema/gordon/internal/common" | ||
| 10 | "github.com/bnema/gordon/internal/server" | 11 | "github.com/bnema/gordon/internal/server" | ||
| 12 | + | "github.com/bnema/gordon/pkg/docker" | |||
| 11 | "github.com/spf13/cobra" | 13 | "github.com/spf13/cobra" | ||
| 12 | ) | 14 | ) | ||
| 13 | 15 | ||||
| 14 | - | var build string | 16 | + | var ( |
| 17 | + | build string | |||
| 18 | + | commit string | |||
| 19 | + | date string | |||
| 20 | + | ) | |||
| 15 | 21 | ||||
| 16 | var rootCmd = &cobra.Command{Use: "gordon"} | 22 | var rootCmd = &cobra.Command{Use: "gordon"} | ||
| 17 | 23 | ||||
| @@ -38,11 +44,32 @@ func main() { | |||||
| 38 | 44 | ||||
| 39 | common.DockerInit(&s.Config.ContainerEngine) | 45 | common.DockerInit(&s.Config.ContainerEngine) | ||
| 40 | 46 | ||||
| 41 | - | // build looks like this: "0.0.901-b98a337" | |||
| 42 | - | //use regex to only get the version number | |||
| 43 | build = regexp.MustCompile(`\d+\.\d+\.\d+`).FindString(build) | 47 | build = regexp.MustCompile(`\d+\.\d+\.\d+`).FindString(build) | ||
| 44 | - | // Set the BuildVersion | 48 | + | s.Config.Build = common.BuildConfig{ |
| 45 | - | s.Config.Build.BuildVersion = build | 49 | + | BuildVersion: build, |
| 50 | + | BuildCommit: commit, | |||
| 51 | + | BuildDate: date, | |||
| 52 | + | ProxyURL: "https://gordon-proxy.bnema.dev", | |||
| 53 | + | } | |||
| 54 | + | ||||
| 55 | + | digest, err := docker.WhoAmI() | |||
| 56 | + | if err != nil { | |||
| 57 | + | log.Println(err) | |||
| 58 | + | } | |||
| 59 | + | ||||
| 60 | + | fmt.Printf("Gordon version %s (%s) built on %s\n", s.Config.Build.BuildVersion, digest, s.Config.Build.BuildDate) | |||
| 61 | + | ||||
| 62 | + | go func() { | |||
| 63 | + | msg, err := common.CheckVersionPeriodically(&s.Config) | |||
| 64 | + | if err != nil { | |||
| 65 | + | log.Println(err) | |||
| 66 | + | } | |||
| 67 | + | ||||
| 68 | + | if msg != "" { | |||
| 69 | + | log.Println(msg) | |||
| 70 | + | } | |||
| 71 | + | ||||
| 72 | + | }() | |||
| 46 | 73 | ||||
| 47 | Execute(a, s) | 74 | Execute(a, s) | ||
| 48 | } | 75 | } | ||
M internal/common/initconfig.go +3 -0
| @@ -23,6 +23,9 @@ type Config struct { | |||
| 23 | 23 | type BuildConfig struct { | |
| 24 | 24 | RunEnv string `yaml:"-"` // come from env | |
| 25 | 25 | BuildVersion string `yaml:"-"` // come from build ldflags | |
| 26 | + | BuildCommit string `yaml:"-"` // come from build ldflags | |
| 27 | + | BuildDate string `yaml:"-"` // come from build ldflags | |
| 28 | + | ProxyURL string `yaml:"-"` | |
| 26 | 29 | } | |
| 27 | 30 | ||
| 28 | 31 | type AdminConfig struct { | |
| @@ -23,6 +23,9 @@ type Config struct { | |||||
| 23 | type BuildConfig struct { | 23 | type BuildConfig struct { | ||
| 24 | RunEnv string `yaml:"-"` // come from env | 24 | RunEnv string `yaml:"-"` // come from env | ||
| 25 | BuildVersion string `yaml:"-"` // come from build ldflags | 25 | BuildVersion string `yaml:"-"` // come from build ldflags | ||
| 26 | + | BuildCommit string `yaml:"-"` // come from build ldflags | |||
| 27 | + | BuildDate string `yaml:"-"` // come from build ldflags | |||
| 28 | + | ProxyURL string `yaml:"-"` | |||
| 26 | } | 29 | } | ||
| 27 | 30 | ||||
| 28 | type AdminConfig struct { | 31 | type AdminConfig struct { | ||
M internal/common/version.go +158 -6
| @@ -1,16 +1,168 @@ | |||
| 1 | 1 | package common | |
| 2 | 2 | ||
| 3 | - | import "time" | |
| 3 | + | import ( | |
| 4 | + | "encoding/json" | |
| 5 | + | "fmt" | |
| 6 | + | "io" | |
| 7 | + | "log" | |
| 8 | + | "net/http" | |
| 9 | + | "runtime" | |
| 10 | + | "strings" | |
| 11 | + | "time" | |
| 4 | 12 | ||
| 5 | - | const checkVersionURL = "https://gordon.bnema.dev/version" | |
| 6 | - | ||
| 7 | - | var timer = time.NewTicker(1 * time.Minute) | |
| 13 | + | "github.com/bnema/gordon/pkg/docker" | |
| 14 | + | ) | |
| 8 | 15 | ||
| 9 | 16 | type CurrentVersion struct { | |
| 10 | 17 | isDocker bool | |
| 11 | 18 | Version string `json:"version"` | |
| 12 | 19 | Commit string `json:"commit"` | |
| 13 | - | Sha256ID string `json:"sha256id"` | |
| 20 | + | Date string `json:"date"` | |
| 21 | + | Digest string `json:"digest"` | |
| 22 | + | } | |
| 23 | + | ||
| 24 | + | // { | |
| 25 | + | // "amd64": { | |
| 26 | + | // "name": "0.0.951-amd64", | |
| 27 | + | // "digest": "sha256:8486058cea46c5a18bc73d19446d6590b8b49cfadd7128ea443abbd69c11ea83" | |
| 28 | + | // }, | |
| 29 | + | // "arm64": { | |
| 30 | + | // "name": "0.0.951-arm64", | |
| 31 | + | // "digest": "sha256:d9c2749117711e0bccd9cf3a3ac36ef7c4aa5487046e584640f2467add57a829" | |
| 32 | + | // } | |
| 33 | + | // } | |
| 34 | + | // VersionInfo represents the JSON structure of the version endpoint response. | |
| 35 | + | ||
| 36 | + | // ArchVersion represents the architecture-specific version details. | |
| 37 | + | type ArchVersion struct { | |
| 38 | + | Name string `json:"name"` | |
| 39 | + | Digest string `json:"digest"` | |
| 40 | + | } | |
| 41 | + | ||
| 42 | + | type VersionInfo struct { | |
| 43 | + | Name string `json:"name"` | |
| 44 | + | Digest string `json:"digest"` | |
| 45 | + | } | |
| 46 | + | ||
| 47 | + | type VersionsResponse struct { | |
| 48 | + | AMD64 VersionInfo `json:"amd64"` | |
| 49 | + | ARM64 VersionInfo `json:"arm64"` | |
| 50 | + | } | |
| 51 | + | ||
| 52 | + | func GetCurrentBuildVersionInfo(c *Config) CurrentVersion { | |
| 53 | + | // Check if the Docker client has been initialized .iscontainer should be at root level | |
| 54 | + | isContainer, err := docker.IsRunningInContainer() | |
| 55 | + | if err != nil { | |
| 56 | + | log.Println(err) | |
| 57 | + | } | |
| 58 | + | ||
| 59 | + | digest, err := docker.WhoAmI() | |
| 60 | + | if err != nil { | |
| 61 | + | log.Println(err) | |
| 62 | + | } | |
| 63 | + | ||
| 64 | + | return CurrentVersion{ | |
| 65 | + | isDocker: isContainer, | |
| 66 | + | Version: c.Build.BuildVersion, | |
| 67 | + | Commit: c.Build.BuildCommit, | |
| 68 | + | Date: c.Build.BuildDate, | |
| 69 | + | Digest: digest, | |
| 70 | + | } | |
| 71 | + | } | |
| 72 | + | ||
| 73 | + | // CheckForNewVersion compares the local and remote version. | |
| 74 | + | // If the remote version is newer, it returns a message stating that a new version is available. | |
| 75 | + | func CheckForNewVersion(local CurrentVersion, remote VersionsResponse) string { | |
| 76 | + | arch := getArch() | |
| 77 | + | ||
| 78 | + | var remoteVersionInfo VersionInfo | |
| 79 | + | switch arch { | |
| 80 | + | case "amd64": | |
| 81 | + | remoteVersionInfo = remote.AMD64 | |
| 82 | + | case "arm64": | |
| 83 | + | remoteVersionInfo = remote.ARM64 | |
| 84 | + | default: | |
| 85 | + | log.Printf("Unknown architecture: %s", arch) | |
| 86 | + | return "" | |
| 87 | + | } | |
| 88 | + | ||
| 89 | + | localVersion := normalizeVersion(local.Version, arch) | |
| 90 | + | remoteVersion := normalizeVersion(remoteVersionInfo.Name, arch) | |
| 91 | + | ||
| 92 | + | // Compare the normalized local version with the remote version | |
| 93 | + | if localVersion != remoteVersion { | |
| 94 | + | return "a new version is available" | |
| 95 | + | } | |
| 96 | + | return "" | |
| 14 | 97 | } | |
| 15 | 98 | ||
| 16 | - | type Response interface{} | |
| 99 | + | // normalizeVersion ensures that the version strings are comparable. | |
| 100 | + | func normalizeVersion(version, arch string) string { | |
| 101 | + | // Assuming the version string might not contain the architecture. | |
| 102 | + | if !strings.Contains(version, arch) { | |
| 103 | + | version = fmt.Sprintf("%s-%s", version, arch) | |
| 104 | + | } | |
| 105 | + | return version | |
| 106 | + | } | |
| 107 | + | ||
| 108 | + | func getArch() string { | |
| 109 | + | return runtime.GOARCH | |
| 110 | + | } | |
| 111 | + | ||
| 112 | + | func CheckVersionPeriodically(c *Config) (string, error) { | |
| 113 | + | timer := time.NewTicker(1 * time.Minute) | |
| 114 | + | defer timer.Stop() | |
| 115 | + | ||
| 116 | + | for range timer.C { | |
| 117 | + | localVersion := getLocalVersion(c) | |
| 118 | + | remoteVersion, err := getRemoteVersion(c) | |
| 119 | + | if err != nil { | |
| 120 | + | log.Printf("Error fetching remote version: %s", err) | |
| 121 | + | continue | |
| 122 | + | } | |
| 123 | + | ||
| 124 | + | message := CheckForNewVersion(localVersion, remoteVersion) | |
| 125 | + | if message != "" { | |
| 126 | + | log.Printf("New version available: %s", message) | |
| 127 | + | // TODO: Add a notification | |
| 128 | + | } | |
| 129 | + | } | |
| 130 | + | ||
| 131 | + | return "", nil | |
| 132 | + | } | |
| 133 | + | ||
| 134 | + | func getLocalVersion(c *Config) CurrentVersion { | |
| 135 | + | return CurrentVersion{ | |
| 136 | + | Version: c.Build.BuildVersion, | |
| 137 | + | Commit: c.Build.BuildCommit, | |
| 138 | + | Date: c.Build.BuildDate, | |
| 139 | + | } | |
| 140 | + | } | |
| 141 | + | ||
| 142 | + | func getRemoteVersion(c *Config) (VersionsResponse, error) { | |
| 143 | + | proxyURL := c.Build.ProxyURL | |
| 144 | + | if proxyURL == "" { | |
| 145 | + | return VersionsResponse{}, fmt.Errorf("proxy URL is empty") | |
| 146 | + | } | |
| 147 | + | ||
| 148 | + | checkVersionEndpoint := proxyURL + "/version" | |
| 149 | + | resp, err := http.Get(checkVersionEndpoint) | |
| 150 | + | if err != nil { | |
| 151 | + | return VersionsResponse{}, err | |
| 152 | + | } | |
| 153 | + | ||
| 154 | + | defer resp.Body.Close() | |
| 155 | + | ||
| 156 | + | body, err := io.ReadAll(resp.Body) | |
| 157 | + | if err != nil { | |
| 158 | + | return VersionsResponse{}, err | |
| 159 | + | } | |
| 160 | + | ||
| 161 | + | var remoteVersionInfo VersionsResponse | |
| 162 | + | err = json.Unmarshal(body, &remoteVersionInfo) | |
| 163 | + | if err != nil { | |
| 164 | + | return VersionsResponse{}, err | |
| 165 | + | } | |
| 166 | + | ||
| 167 | + | return remoteVersionInfo, nil | |
| 168 | + | } | |
| @@ -1,16 +1,168 @@ | |||||
| 1 | package common | 1 | package common | ||
| 2 | 2 | ||||
| 3 | - | import "time" | 3 | + | import ( |
| 4 | + | "encoding/json" | |||
| 5 | + | "fmt" | |||
| 6 | + | "io" | |||
| 7 | + | "log" | |||
| 8 | + | "net/http" | |||
| 9 | + | "runtime" | |||
| 10 | + | "strings" | |||
| 11 | + | "time" | |||
| 4 | 12 | ||||
| 5 | - | const checkVersionURL = "https://gordon.bnema.dev/version" | 13 | + | "github.com/bnema/gordon/pkg/docker" |
| 6 | - | 14 | + | ) | |
| 7 | - | var timer = time.NewTicker(1 * time.Minute) | |||
| 8 | 15 | ||||
| 9 | type CurrentVersion struct { | 16 | type CurrentVersion struct { | ||
| 10 | isDocker bool | 17 | isDocker bool | ||
| 11 | Version string `json:"version"` | 18 | Version string `json:"version"` | ||
| 12 | Commit string `json:"commit"` | 19 | Commit string `json:"commit"` | ||
| 13 | - | Sha256ID string `json:"sha256id"` | 20 | + | Date string `json:"date"` |
| 21 | + | Digest string `json:"digest"` | |||
| 22 | + | } | |||
| 23 | + | ||||
| 24 | + | // { | |||
| 25 | + | // "amd64": { | |||
| 26 | + | // "name": "0.0.951-amd64", | |||
| 27 | + | // "digest": "sha256:8486058cea46c5a18bc73d19446d6590b8b49cfadd7128ea443abbd69c11ea83" | |||
| 28 | + | // }, | |||
| 29 | + | // "arm64": { | |||
| 30 | + | // "name": "0.0.951-arm64", | |||
| 31 | + | // "digest": "sha256:d9c2749117711e0bccd9cf3a3ac36ef7c4aa5487046e584640f2467add57a829" | |||
| 32 | + | // } | |||
| 33 | + | // } | |||
| 34 | + | // VersionInfo represents the JSON structure of the version endpoint response. | |||
| 35 | + | ||||
| 36 | + | // ArchVersion represents the architecture-specific version details. | |||
| 37 | + | type ArchVersion struct { | |||
| 38 | + | Name string `json:"name"` | |||
| 39 | + | Digest string `json:"digest"` | |||
| 40 | + | } | |||
| 41 | + | ||||
| 42 | + | type VersionInfo struct { | |||
| 43 | + | Name string `json:"name"` | |||
| 44 | + | Digest string `json:"digest"` | |||
| 45 | + | } | |||
| 46 | + | ||||
| 47 | + | type VersionsResponse struct { | |||
| 48 | + | AMD64 VersionInfo `json:"amd64"` | |||
| 49 | + | ARM64 VersionInfo `json:"arm64"` | |||
| 50 | + | } | |||
| 51 | + | ||||
| 52 | + | func GetCurrentBuildVersionInfo(c *Config) CurrentVersion { | |||
| 53 | + | // Check if the Docker client has been initialized .iscontainer should be at root level | |||
| 54 | + | isContainer, err := docker.IsRunningInContainer() | |||
| 55 | + | if err != nil { | |||
| 56 | + | log.Println(err) | |||
| 57 | + | } | |||
| 58 | + | ||||
| 59 | + | digest, err := docker.WhoAmI() | |||
| 60 | + | if err != nil { | |||
| 61 | + | log.Println(err) | |||
| 62 | + | } | |||
| 63 | + | ||||
| 64 | + | return CurrentVersion{ | |||
| 65 | + | isDocker: isContainer, | |||
| 66 | + | Version: c.Build.BuildVersion, | |||
| 67 | + | Commit: c.Build.BuildCommit, | |||
| 68 | + | Date: c.Build.BuildDate, | |||
| 69 | + | Digest: digest, | |||
| 70 | + | } | |||
| 71 | + | } | |||
| 72 | + | ||||
| 73 | + | // CheckForNewVersion compares the local and remote version. | |||
| 74 | + | // If the remote version is newer, it returns a message stating that a new version is available. | |||
| 75 | + | func CheckForNewVersion(local CurrentVersion, remote VersionsResponse) string { | |||
| 76 | + | arch := getArch() | |||
| 77 | + | ||||
| 78 | + | var remoteVersionInfo VersionInfo | |||
| 79 | + | switch arch { | |||
| 80 | + | case "amd64": | |||
| 81 | + | remoteVersionInfo = remote.AMD64 | |||
| 82 | + | case "arm64": | |||
| 83 | + | remoteVersionInfo = remote.ARM64 | |||
| 84 | + | default: | |||
| 85 | + | log.Printf("Unknown architecture: %s", arch) | |||
| 86 | + | return "" | |||
| 87 | + | } | |||
| 88 | + | ||||
| 89 | + | localVersion := normalizeVersion(local.Version, arch) | |||
| 90 | + | remoteVersion := normalizeVersion(remoteVersionInfo.Name, arch) | |||
| 91 | + | ||||
| 92 | + | // Compare the normalized local version with the remote version | |||
| 93 | + | if localVersion != remoteVersion { | |||
| 94 | + | return "a new version is available" | |||
| 95 | + | } | |||
| 96 | + | return "" | |||
| 14 | } | 97 | } | ||
| 15 | 98 | ||||
| 16 | - | type Response interface{} | 99 | + | // normalizeVersion ensures that the version strings are comparable. |
| 100 | + | func normalizeVersion(version, arch string) string { | |||
| 101 | + | // Assuming the version string might not contain the architecture. | |||
| 102 | + | if !strings.Contains(version, arch) { | |||
| 103 | + | version = fmt.Sprintf("%s-%s", version, arch) | |||
| 104 | + | } | |||
| 105 | + | return version | |||
| 106 | + | } | |||
| 107 | + | ||||
| 108 | + | func getArch() string { | |||
| 109 | + | return runtime.GOARCH | |||
| 110 | + | } | |||
| 111 | + | ||||
| 112 | + | func CheckVersionPeriodically(c *Config) (string, error) { | |||
| 113 | + | timer := time.NewTicker(1 * time.Minute) | |||
| 114 | + | defer timer.Stop() | |||
| 115 | + | ||||
| 116 | + | for range timer.C { | |||
| 117 | + | localVersion := getLocalVersion(c) | |||
| 118 | + | remoteVersion, err := getRemoteVersion(c) | |||
| 119 | + | if err != nil { | |||
| 120 | + | log.Printf("Error fetching remote version: %s", err) | |||
| 121 | + | continue | |||
| 122 | + | } | |||
| 123 | + | ||||
| 124 | + | message := CheckForNewVersion(localVersion, remoteVersion) | |||
| 125 | + | if message != "" { | |||
| 126 | + | log.Printf("New version available: %s", message) | |||
| 127 | + | // TODO: Add a notification | |||
| 128 | + | } | |||
| 129 | + | } | |||
| 130 | + | ||||
| 131 | + | return "", nil | |||
| 132 | + | } | |||
| 133 | + | ||||
| 134 | + | func getLocalVersion(c *Config) CurrentVersion { | |||
| 135 | + | return CurrentVersion{ | |||
| 136 | + | Version: c.Build.BuildVersion, | |||
| 137 | + | Commit: c.Build.BuildCommit, | |||
| 138 | + | Date: c.Build.BuildDate, | |||
| 139 | + | } | |||
| 140 | + | } | |||
| 141 | + | ||||
| 142 | + | func getRemoteVersion(c *Config) (VersionsResponse, error) { | |||
| 143 | + | proxyURL := c.Build.ProxyURL | |||
| 144 | + | if proxyURL == "" { | |||
| 145 | + | return VersionsResponse{}, fmt.Errorf("proxy URL is empty") | |||
| 146 | + | } | |||
| 147 | + | ||||
| 148 | + | checkVersionEndpoint := proxyURL + "/version" | |||
| 149 | + | resp, err := http.Get(checkVersionEndpoint) | |||
| 150 | + | if err != nil { | |||
| 151 | + | return VersionsResponse{}, err | |||
| 152 | + | } | |||
| 153 | + | ||||
| 154 | + | defer resp.Body.Close() | |||
| 155 | + | ||||
| 156 | + | body, err := io.ReadAll(resp.Body) | |||
| 157 | + | if err != nil { | |||
| 158 | + | return VersionsResponse{}, err | |||
| 159 | + | } | |||
| 160 | + | ||||
| 161 | + | var remoteVersionInfo VersionsResponse | |||
| 162 | + | err = json.Unmarshal(body, &remoteVersionInfo) | |||
| 163 | + | if err != nil { | |||
| 164 | + | return VersionsResponse{}, err | |||
| 165 | + | } | |||
| 166 | + | ||||
| 167 | + | return remoteVersionInfo, nil | |||
| 168 | + | } | |||
M internal/httpserve/handler/oauth.go +3 -1
| @@ -75,8 +75,10 @@ func StartOAuthGithub(c echo.Context, a *server.App) error { | |||
| 75 | 75 | redirectDomain := a.GenerateOauthCallbackURL() | |
| 76 | 76 | encodedState := base64.StdEncoding.EncodeToString([]byte("redirectDomain:" + redirectDomain)) | |
| 77 | 77 | // Redirect to Gordon's Proxy to grab the oauth access | |
| 78 | + | proxyURL := a.Config.Build.ProxyURL | |
| 78 | 79 | oauthURL := fmt.Sprintf( | |
| 79 | - | "https://gordon.bnema.dev/github-proxy/authorize?client_id=%s&redirect_uri=%s&state=%s", | |
| 80 | + | "%s/github/authorize?client_id=%s&redirect_uri=%s&state=%s", | |
| 81 | + | proxyURL, | |
| 80 | 82 | clientID, | |
| 81 | 83 | redirectDomain, | |
| 82 | 84 | encodedState, | |
| @@ -75,8 +75,10 @@ func StartOAuthGithub(c echo.Context, a *server.App) error { | |||||
| 75 | redirectDomain := a.GenerateOauthCallbackURL() | 75 | redirectDomain := a.GenerateOauthCallbackURL() | ||
| 76 | encodedState := base64.StdEncoding.EncodeToString([]byte("redirectDomain:" + redirectDomain)) | 76 | encodedState := base64.StdEncoding.EncodeToString([]byte("redirectDomain:" + redirectDomain)) | ||
| 77 | // Redirect to Gordon's Proxy to grab the oauth access | 77 | // Redirect to Gordon's Proxy to grab the oauth access | ||
| 78 | + | proxyURL := a.Config.Build.ProxyURL | |||
| 78 | oauthURL := fmt.Sprintf( | 79 | oauthURL := fmt.Sprintf( | ||
| 79 | - | "https://gordon.bnema.dev/github-proxy/authorize?client_id=%s&redirect_uri=%s&state=%s", | 80 | + | "%s/github/authorize?client_id=%s&redirect_uri=%s&state=%s", |
| 81 | + | proxyURL, | |||
| 80 | clientID, | 82 | clientID, | ||
| 81 | redirectDomain, | 83 | redirectDomain, | ||
| 82 | encodedState, | 84 | encodedState, | ||
M pkg/docker/images.go +13 -1
| @@ -78,7 +78,6 @@ func ImportImageToEngine(imageFilePath string) error { | |||
| 78 | 78 | // ExportImageFromEngine exports an image from the Docker engine and returns it as an io.Reader | |
| 79 | 79 | func ExportImageFromEngine(imageID string) (io.ReadCloser, error) { | |
| 80 | 80 | // Check if the Docker client has been initialized | |
| 81 | - | CheckIfInitialized() | |
| 82 | 81 | ||
| 83 | 82 | // Get the image information using the Docker client | |
| 84 | 83 | imageInfo, err := GetImageInfo(imageID) | |
| @@ -142,3 +141,16 @@ func GetImageName(imageID string) (string, error) { | |||
| 142 | 141 | ||
| 143 | 142 | return imageInfo.RepoDigests[0], nil | |
| 144 | 143 | } | |
| 144 | + | ||
| 145 | + | // WhoAmI attempts to identify the Docker image digest of the container running this code. | |
| 146 | + | func WhoAmI() (string, error) { | |
| 147 | + | gordonImage := "ghcr.io/bnema/gordon:latest" | |
| 148 | + | ||
| 149 | + | // Get the image information using the Docker client | |
| 150 | + | imageInfo, _, err := dockerCli.ImageInspectWithRaw(context.Background(), gordonImage) | |
| 151 | + | if err != nil { | |
| 152 | + | return "", err | |
| 153 | + | } | |
| 154 | + | ||
| 155 | + | return imageInfo.ID, nil | |
| 156 | + | } | |
| @@ -78,7 +78,6 @@ func ImportImageToEngine(imageFilePath string) error { | |||||
| 78 | // ExportImageFromEngine exports an image from the Docker engine and returns it as an io.Reader | 78 | // ExportImageFromEngine exports an image from the Docker engine and returns it as an io.Reader | ||
| 79 | func ExportImageFromEngine(imageID string) (io.ReadCloser, error) { | 79 | func ExportImageFromEngine(imageID string) (io.ReadCloser, error) { | ||
| 80 | // Check if the Docker client has been initialized | 80 | // Check if the Docker client has been initialized | ||
| 81 | - | CheckIfInitialized() | |||
| 82 | 81 | ||||
| 83 | // Get the image information using the Docker client | 82 | // Get the image information using the Docker client | ||
| 84 | imageInfo, err := GetImageInfo(imageID) | 83 | imageInfo, err := GetImageInfo(imageID) | ||
| @@ -142,3 +141,16 @@ func GetImageName(imageID string) (string, error) { | |||||
| 142 | 141 | ||||
| 143 | return imageInfo.RepoDigests[0], nil | 142 | return imageInfo.RepoDigests[0], nil | ||
| 144 | } | 143 | } | ||
| 144 | + | ||||
| 145 | + | // WhoAmI attempts to identify the Docker image digest of the container running this code. | |||
| 146 | + | func WhoAmI() (string, error) { | |||
| 147 | + | gordonImage := "ghcr.io/bnema/gordon:latest" | |||
| 148 | + | ||||
| 149 | + | // Get the image information using the Docker client | |||
| 150 | + | imageInfo, _, err := dockerCli.ImageInspectWithRaw(context.Background(), gordonImage) | |||
| 151 | + | if err != nil { | |||
| 152 | + | return "", err | |||
| 153 | + | } | |||
| 154 | + | ||||
| 155 | + | return imageInfo.ID, nil | |||
| 156 | + | } | |||