break down release versions and fix server tests

This commit is contained in:
Sergio Moura
2023-09-12 10:09:38 -04:00
parent 60a0e20dd9
commit 0d30011a33
7 changed files with 225 additions and 171 deletions

View File

@ -2,21 +2,16 @@ package main
import (
"context"
"encoding/json"
"fmt"
"github.com/ddworken/hishtory/internal/release"
"github.com/ddworken/hishtory/internal/server"
"io"
"log"
"net/http"
"os"
"runtime"
"strconv"
"strings"
"time"
"github.com/DataDog/datadog-go/statsd"
"github.com/ddworken/hishtory/internal/database"
"github.com/ddworken/hishtory/shared"
_ "github.com/lib/pq"
"gorm.io/gorm"
"gorm.io/gorm/logger"
@ -28,9 +23,8 @@ const (
)
var (
GLOBAL_DB *database.DB
GLOBAL_STATSD *statsd.Client
ReleaseVersion string = "UNKNOWN"
GLOBAL_DB *database.DB
GLOBAL_STATSD *statsd.Client
)
func isTestEnvironment() bool {
@ -102,15 +96,14 @@ func OpenDB() (*database.DB, error) {
}
func init() {
if ReleaseVersion == "UNKNOWN" && !isTestEnvironment() {
if release.Version == "UNKNOWN" && !isTestEnvironment() {
panic("server.go was built without a ReleaseVersion!")
}
InitDB()
go runBackgroundJobs(context.Background())
}
func cron(ctx context.Context, db *database.DB, stats *statsd.Client) error {
if err := updateReleaseVersion(); err != nil {
if err := release.UpdateReleaseVersion(); err != nil {
return fmt.Errorf("updateReleaseVersion: %w", err)
}
@ -125,7 +118,7 @@ func cron(ctx context.Context, db *database.DB, stats *statsd.Client) error {
return nil
}
func runBackgroundJobs(ctx context.Context) {
func runBackgroundJobs(ctx context.Context, srv *server.Server) {
time.Sleep(5 * time.Second)
for {
err := cron(ctx, GLOBAL_DB, GLOBAL_STATSD)
@ -135,80 +128,12 @@ func runBackgroundJobs(ctx context.Context) {
// cron no longer panics, panicking here.
panic(err)
}
srv.UpdateReleaseVersion(release.Version, release.BuildUpdateInfo(release.Version))
time.Sleep(10 * time.Minute)
}
}
type releaseInfo struct {
Name string `json:"name"`
}
func updateReleaseVersion() error {
resp, err := http.Get("https://api.github.com/repos/ddworken/hishtory/releases/latest")
if err != nil {
return fmt.Errorf("failed to get latest release version: %w", err)
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("failed to read github API response body: %w", err)
}
if resp.StatusCode == 403 && strings.Contains(string(respBody), "API rate limit exceeded for ") {
return nil
}
if resp.StatusCode != 200 {
return fmt.Errorf("failed to call github API, status_code=%d, body=%#v", resp.StatusCode, string(respBody))
}
var info releaseInfo
err = json.Unmarshal(respBody, &info)
if err != nil {
return fmt.Errorf("failed to parse github API response: %w", err)
}
latestVersionTag := info.Name
ReleaseVersion = decrementVersionIfInvalid(latestVersionTag)
return nil
}
func decrementVersionIfInvalid(initialVersion string) string {
// Decrements the version up to 5 times if the version doesn't have valid binaries yet.
version := initialVersion
for i := 0; i < 5; i++ {
updateInfo := buildUpdateInfo(version)
err := assertValidUpdate(updateInfo)
if err == nil {
fmt.Printf("Found a valid version: %v\n", version)
return version
}
fmt.Printf("Found %s to be an invalid version: %v\n", version, err)
version, err = decrementVersion(version)
if err != nil {
fmt.Printf("Failed to decrement version after finding the latest version was invalid: %v\n", err)
return initialVersion
}
}
fmt.Printf("Decremented the version 5 times and failed to find a valid version version number, initial version number: %v, last checked version number: %v\n", initialVersion, version)
return initialVersion
}
func assertValidUpdate(updateInfo shared.UpdateInfo) error {
urls := []string{updateInfo.LinuxAmd64Url, updateInfo.LinuxAmd64AttestationUrl, updateInfo.LinuxArm64Url, updateInfo.LinuxArm64AttestationUrl,
updateInfo.LinuxArm7Url, updateInfo.LinuxArm7AttestationUrl,
updateInfo.DarwinAmd64Url, updateInfo.DarwinAmd64UnsignedUrl, updateInfo.DarwinAmd64AttestationUrl,
updateInfo.DarwinArm64Url, updateInfo.DarwinArm64UnsignedUrl, updateInfo.DarwinArm64AttestationUrl}
for _, url := range urls {
resp, err := http.Get(url)
if err != nil {
return fmt.Errorf("failed to retrieve URL %#v: %w", url, err)
}
defer resp.Body.Close()
if resp.StatusCode == 404 {
return fmt.Errorf("URL %#v returned 404", url)
}
}
return nil
}
func InitDB() {
func InitDB() *database.DB {
var err error
GLOBAL_DB, err = OpenDB()
if err != nil {
@ -228,39 +153,8 @@ func InitDB() {
panic(fmt.Errorf("failed to set max idle conns: %w", err))
}
}
}
func decrementVersion(version string) (string, error) {
if version == "UNKNOWN" {
return "", fmt.Errorf("cannot decrement UNKNOWN")
}
parts := strings.Split(version, ".")
if len(parts) != 2 {
return "", fmt.Errorf("invalid version: %s", version)
}
versionNumber, err := strconv.Atoi(parts[1])
if err != nil {
return "", fmt.Errorf("invalid version: %s", version)
}
return parts[0] + "." + strconv.Itoa(versionNumber-1), nil
}
func buildUpdateInfo(version string) shared.UpdateInfo {
return shared.UpdateInfo{
LinuxAmd64Url: fmt.Sprintf("https://github.com/ddworken/hishtory/releases/download/%s/hishtory-linux-amd64", version),
LinuxAmd64AttestationUrl: fmt.Sprintf("https://github.com/ddworken/hishtory/releases/download/%s/hishtory-linux-amd64.intoto.jsonl", version),
LinuxArm64Url: fmt.Sprintf("https://github.com/ddworken/hishtory/releases/download/%s/hishtory-linux-arm64", version),
LinuxArm64AttestationUrl: fmt.Sprintf("https://github.com/ddworken/hishtory/releases/download/%s/hishtory-linux-arm64.intoto.jsonl", version),
LinuxArm7Url: fmt.Sprintf("https://github.com/ddworken/hishtory/releases/download/%s/hishtory-linux-arm", version),
LinuxArm7AttestationUrl: fmt.Sprintf("https://github.com/ddworken/hishtory/releases/download/%s/hishtory-linux-arm.intoto.jsonl", version),
DarwinAmd64Url: fmt.Sprintf("https://github.com/ddworken/hishtory/releases/download/%s/hishtory-darwin-amd64", version),
DarwinAmd64UnsignedUrl: fmt.Sprintf("https://github.com/ddworken/hishtory/releases/download/%s/hishtory-darwin-amd64-unsigned", version),
DarwinAmd64AttestationUrl: fmt.Sprintf("https://github.com/ddworken/hishtory/releases/download/%s/hishtory-darwin-amd64.intoto.jsonl", version),
DarwinArm64Url: fmt.Sprintf("https://github.com/ddworken/hishtory/releases/download/%s/hishtory-darwin-arm64", version),
DarwinArm64UnsignedUrl: fmt.Sprintf("https://github.com/ddworken/hishtory/releases/download/%s/hishtory-darwin-arm64-unsigned", version),
DarwinArm64AttestationUrl: fmt.Sprintf("https://github.com/ddworken/hishtory/releases/download/%s/hishtory-darwin-arm64.intoto.jsonl", version),
Version: version,
}
return GLOBAL_DB
}
func main() {
@ -275,13 +169,15 @@ func main() {
srv := server.NewServer(
GLOBAL_DB,
server.WithStatsd(s),
server.WithReleaseVersion(ReleaseVersion),
server.WithReleaseVersion(release.Version),
server.IsTestEnvironment(isTestEnvironment()),
server.IsProductionEnvironment(isProductionEnvironment()),
server.WithCron(cron),
server.WithUpdateInfo(buildUpdateInfo(ReleaseVersion)),
server.WithUpdateInfo(release.BuildUpdateInfo(release.Version)),
)
go runBackgroundJobs(context.Background(), srv)
if err := srv.Run(context.Background(), ":8080"); err != nil {
panic(err)
}