Move to setting version info explicitly in linker flags
Some checks failed
/ golint (push) Failing after 12s
Some checks failed
/ golint (push) Failing after 12s
We don't have go built-in VCS information in a nix build because the git repository isn't present. After struggling to build an overlay that would provide it, I decided this path is easier of just injecting in the data that we need. Issue: #5
This commit is contained in:
parent
81826f853e
commit
d4cbfb960e
8 changed files with 119 additions and 79 deletions
|
|
@ -322,7 +322,7 @@ type tegolaURLs struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRoot(ctx context.Context, r *http.Request, q resource.QueryParams) (*about, *nhttp.ErrorWithStatus) {
|
func getRoot(ctx context.Context, r *http.Request, q resource.QueryParams) (*about, *nhttp.ErrorWithStatus) {
|
||||||
v := version.Get()
|
v := GetVersionInfo()
|
||||||
return &about{
|
return &about{
|
||||||
Environment: config.Environment,
|
Environment: config.Environment,
|
||||||
SentryDSN: config.SentryDSNFrontend,
|
SentryDSN: config.SentryDSNFrontend,
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"source.gleipnir.technology/Gleipnir/nidus-sync/lint"
|
"source.gleipnir.technology/Gleipnir/nidus-sync/lint"
|
||||||
"source.gleipnir.technology/Gleipnir/nidus-sync/platform"
|
"source.gleipnir.technology/Gleipnir/nidus-sync/platform"
|
||||||
"source.gleipnir.technology/Gleipnir/nidus-sync/platform/event"
|
"source.gleipnir.technology/Gleipnir/nidus-sync/platform/event"
|
||||||
"source.gleipnir.technology/Gleipnir/nidus-sync/version"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var connectionsSSE map[*ConnectionSSE]bool = make(map[*ConnectionSSE]bool, 0)
|
var connectionsSSE map[*ConnectionSSE]bool = make(map[*ConnectionSSE]bool, 0)
|
||||||
|
|
@ -41,7 +40,7 @@ type Status struct {
|
||||||
|
|
||||||
func (c *ConnectionSSE) SendEvent(w http.ResponseWriter, m platform.Event) error {
|
func (c *ConnectionSSE) SendEvent(w http.ResponseWriter, m platform.Event) error {
|
||||||
if m.Type == event.EventTypeShutdown {
|
if m.Type == event.EventTypeShutdown {
|
||||||
v := version.Get()
|
v := GetVersionInfo()
|
||||||
return send(w, Status{
|
return send(w, Status{
|
||||||
BuildTime: v.BuildTime,
|
BuildTime: v.BuildTime,
|
||||||
IsModified: v.IsModified,
|
IsModified: v.IsModified,
|
||||||
|
|
@ -121,7 +120,7 @@ func streamEvents(w http.ResponseWriter, r *http.Request, u platform.User) {
|
||||||
log.Debug().Int32("org", u.Organization.ID).Int("user", u.ID).Str("id", uid.String()).Msg("connected SSE client")
|
log.Debug().Int32("org", u.Organization.ID).Int("user", u.ID).Str("id", uid.String()).Msg("connected SSE client")
|
||||||
|
|
||||||
// Send an initial connected event
|
// Send an initial connected event
|
||||||
v := version.Get()
|
v := GetVersionInfo()
|
||||||
status := Status{
|
status := Status{
|
||||||
BuildTime: v.BuildTime,
|
BuildTime: v.BuildTime,
|
||||||
IsModified: v.IsModified,
|
IsModified: v.IsModified,
|
||||||
|
|
|
||||||
16
api/version.go
Normal file
16
api/version.go
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"source.gleipnir.technology/Gleipnir/nidus-sync/version"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
versionInfo version.VersionInfo
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetVersionInfo() version.VersionInfo {
|
||||||
|
return versionInfo
|
||||||
|
}
|
||||||
|
func SetVersionInfo(v version.VersionInfo) {
|
||||||
|
versionInfo = v
|
||||||
|
}
|
||||||
17
default.nix
17
default.nix
|
|
@ -1,4 +1,4 @@
|
||||||
{ pkgs ? import <nixpkgs> { }, proj ? pkgs.proj }:
|
{ ldflags, version, pkgs ? import <nixpkgs> { }, proj ? pkgs.proj }:
|
||||||
|
|
||||||
let
|
let
|
||||||
# Get commit timestamp at eval time (pure)
|
# Get commit timestamp at eval time (pure)
|
||||||
|
|
@ -12,24 +12,12 @@ let
|
||||||
else "0";
|
else "0";
|
||||||
in
|
in
|
||||||
pkgs.buildGoModule rec {
|
pkgs.buildGoModule rec {
|
||||||
|
inherit ldflags version;
|
||||||
pname = "nidus-sync";
|
pname = "nidus-sync";
|
||||||
version = "0.0.12";
|
|
||||||
src = ./.;
|
src = ./.;
|
||||||
|
|
||||||
gitRevision =
|
|
||||||
if builtins.pathExists ./.git
|
|
||||||
then pkgs.lib.commitIdFromGitRepo ./.git
|
|
||||||
else "unknown";
|
|
||||||
|
|
||||||
buildTime = getCommitTime;
|
buildTime = getCommitTime;
|
||||||
|
|
||||||
ldflags = [
|
|
||||||
"-s"
|
|
||||||
"-w"
|
|
||||||
"-X main.Version=${version}"
|
|
||||||
"-X main.Commit=${gitRevision}"
|
|
||||||
"-X main.BuildTime=${buildTime}"
|
|
||||||
];
|
|
||||||
meta = {
|
meta = {
|
||||||
description = "Nidus Sync";
|
description = "Nidus Sync";
|
||||||
homepage = "https://github.com/Gleipnir-Technology/nidus-sync";
|
homepage = "https://github.com/Gleipnir-Technology/nidus-sync";
|
||||||
|
|
@ -74,4 +62,5 @@ pkgs.buildGoModule rec {
|
||||||
cp -r vite/rmo/static/gen/rmo $out/share/frontend/
|
cp -r vite/rmo/static/gen/rmo $out/share/frontend/
|
||||||
cp -r vite/rmo/static/gen/sync $out/share/frontend/
|
cp -r vite/rmo/static/gen/sync $out/share/frontend/
|
||||||
'';
|
'';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
6
flake.lock
generated
6
flake.lock
generated
|
|
@ -75,11 +75,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772542754,
|
"lastModified": 1778869304,
|
||||||
"narHash": "sha256-WGV2hy+VIeQsYXpsLjdr4GvHv5eECMISX1zKLTedhdg=",
|
"narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "8c809a146a140c5c8806f13399592dbcb1bb5dc4",
|
"rev": "d233902339c02a9c334e7e593de68855ad26c4cb",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
28
flake.nix
28
flake.nix
|
|
@ -21,8 +21,32 @@
|
||||||
projPkg = proj.packages.${system}.default;
|
projPkg = proj.packages.${system}.default;
|
||||||
|
|
||||||
package = pkgs.callPackage ./default.nix {
|
package = pkgs.callPackage ./default.nix {
|
||||||
proj = projPkg;
|
ldflags = ldflags;
|
||||||
};
|
proj = projPkg;
|
||||||
|
version = packageVersion;
|
||||||
|
};
|
||||||
|
# Pull VCS metadata from the flake's own git source.
|
||||||
|
# These fields are available when the flake lives inside a git checkout.
|
||||||
|
gitRevision = self.sourceInfo.rev or "dirty";
|
||||||
|
gitShortRev = self.sourceInfo.shortRev or "dirty";
|
||||||
|
gitDateTime = self.sourceInfo.lastModifiedDate or "unknown";
|
||||||
|
|
||||||
|
# Derive a human-readable version from the git date + short rev.
|
||||||
|
# lastModifiedDate is YYYYMMDDHHMMSS; pull out just YYYY-MM-DD.
|
||||||
|
packageVersion =
|
||||||
|
let
|
||||||
|
y = builtins.substring 0 4 gitDateTime;
|
||||||
|
m = builtins.substring 4 2 gitDateTime;
|
||||||
|
d = builtins.substring 6 2 gitDateTime;
|
||||||
|
in "${y}-${m}-${d}.${gitShortRev}";
|
||||||
|
|
||||||
|
ldflags = [
|
||||||
|
"-s" "-w"
|
||||||
|
"-X main.BuildTime=${gitDateTime}"
|
||||||
|
"-X main.Revision=${gitRevision}"
|
||||||
|
"-X main.Version=${packageVersion}"
|
||||||
|
];
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
packages.default = package;
|
packages.default = package;
|
||||||
|
|
|
||||||
70
main.go
70
main.go
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
//"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -33,6 +34,13 @@ import (
|
||||||
"source.gleipnir.technology/Gleipnir/nidus-sync/version"
|
"source.gleipnir.technology/Gleipnir/nidus-sync/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// These will be set by ldflags at build time by Nix
|
||||||
|
var (
|
||||||
|
BuildTime = "unknown"
|
||||||
|
Revision = "unknown"
|
||||||
|
Version = "dev"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := config.Parse()
|
err := config.Parse()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -46,8 +54,19 @@ func main() {
|
||||||
log.Warn().Msg("Forcing production mode for testing templates")
|
log.Warn().Msg("Forcing production mode for testing templates")
|
||||||
config.Environment = "PRODUCTION"
|
config.Environment = "PRODUCTION"
|
||||||
}
|
}
|
||||||
v := version.Get()
|
v := GetVersionInfo()
|
||||||
log.Info().Str("environment", config.Environment).Bool("is-prod", config.IsProductionEnvironment()).Str("revision", v.Revision).Str("build_time", v.BuildTime.String()).Bool("is modified", v.IsModified).Msg("Starting")
|
log.Info().
|
||||||
|
Str("environment", config.Environment).
|
||||||
|
Bool("is-prod", config.IsProductionEnvironment()).
|
||||||
|
Str("revision", v.Revision).
|
||||||
|
Str("build_time", v.BuildTime.String()).
|
||||||
|
Bool("is modified", v.IsModified).
|
||||||
|
Str("Version", Version).
|
||||||
|
Str("Revision", Revision).
|
||||||
|
Str("BuildDate", BuildTime).
|
||||||
|
Msg("Starting")
|
||||||
|
api.SetVersionInfo(v)
|
||||||
|
|
||||||
err = sentry.Init(sentry.ClientOptions{
|
err = sentry.Init(sentry.ClientOptions{
|
||||||
Debug: false, //!config.IsProductionEnvironment(),
|
Debug: false, //!config.IsProductionEnvironment(),
|
||||||
Dsn: config.SentryDSN,
|
Dsn: config.SentryDSN,
|
||||||
|
|
@ -285,3 +304,50 @@ func LoggerMiddleware(logger *zerolog.Logger) func(next http.Handler) http.Handl
|
||||||
return http.HandlerFunc(fn)
|
return http.HandlerFunc(fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func GetVersionInfo() (version.VersionInfo, error) {
|
||||||
|
// Try ldflags first (set by Nix build)
|
||||||
|
if Revision != "" && Revision != "unknown" {
|
||||||
|
build_time, err := parseNixTime(BuildTime)
|
||||||
|
if err != nil {
|
||||||
|
return version.VersionInfo{}, fmt.Errorf("parse nix time: %w", err)
|
||||||
|
}
|
||||||
|
return version.VersionInfo{
|
||||||
|
BuildTime: build_time,
|
||||||
|
IsModified: Revision == "dirty",
|
||||||
|
Revision: Revision,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to debug.ReadBuildInfo() for development
|
||||||
|
info, ok := debug.ReadBuildInfo()
|
||||||
|
if !ok {
|
||||||
|
return version.VersionInfo{}, fmt.Errorf("read build info not ok")
|
||||||
|
}
|
||||||
|
|
||||||
|
var v version.VersionInfo
|
||||||
|
for _, setting := range info.Settings {
|
||||||
|
switch setting.Key {
|
||||||
|
case "vcs.modified":
|
||||||
|
v.IsModified = setting.Value == "true"
|
||||||
|
case "vcs.revision":
|
||||||
|
if len(setting.Value) > 7 {
|
||||||
|
v.Revision = setting.Value[:7]
|
||||||
|
} else {
|
||||||
|
v.Revision = setting.Value
|
||||||
|
}
|
||||||
|
case "vcs.time":
|
||||||
|
if t, err := time.Parse(time.RFC3339, setting.Value); err == nil {
|
||||||
|
v.BuildTime = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
func parseNixTime(timestamp string) (time.Time, error) {
|
||||||
|
layout := "20060102150405"
|
||||||
|
t, err := time.Parse(layout, timestamp)
|
||||||
|
if err != nil {
|
||||||
|
return time.Time{}, err
|
||||||
|
}
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,65 +1,11 @@
|
||||||
package version
|
package version
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"runtime/debug"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// These will be set by ldflags at build time
|
|
||||||
var (
|
|
||||||
Version = "dev"
|
|
||||||
Commit = ""
|
|
||||||
BuildTime = "0"
|
|
||||||
IsModified = "false"
|
|
||||||
)
|
|
||||||
|
|
||||||
type VersionInfo struct {
|
type VersionInfo struct {
|
||||||
BuildTime time.Time `json:"build_time"`
|
BuildTime time.Time `json:"build_time"`
|
||||||
IsModified bool `json:"is_modified"`
|
IsModified bool `json:"is_modified"`
|
||||||
Revision string `json:"revision"`
|
Revision string `json:"revision"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func Get() VersionInfo {
|
|
||||||
// Try ldflags first (set by Nix build)
|
|
||||||
if Commit != "" && Commit != "unknown" {
|
|
||||||
var buildTime time.Time
|
|
||||||
if timestamp, err := strconv.ParseInt(BuildTime, 10, 64); err == nil && timestamp > 0 {
|
|
||||||
buildTime = time.Unix(timestamp, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
return VersionInfo{
|
|
||||||
Revision: Commit,
|
|
||||||
BuildTime: buildTime,
|
|
||||||
IsModified: IsModified == "true",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fallback to debug.ReadBuildInfo() for development
|
|
||||||
info, ok := debug.ReadBuildInfo()
|
|
||||||
if !ok {
|
|
||||||
return VersionInfo{
|
|
||||||
Revision: "unknown",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var version VersionInfo
|
|
||||||
for _, setting := range info.Settings {
|
|
||||||
switch setting.Key {
|
|
||||||
case "vcs.modified":
|
|
||||||
version.IsModified = setting.Value == "true"
|
|
||||||
case "vcs.revision":
|
|
||||||
if len(setting.Value) > 7 {
|
|
||||||
version.Revision = setting.Value[:7]
|
|
||||||
} else {
|
|
||||||
version.Revision = setting.Value
|
|
||||||
}
|
|
||||||
case "vcs.time":
|
|
||||||
if t, err := time.Parse(time.RFC3339, setting.Value); err == nil {
|
|
||||||
version.BuildTime = t
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return version
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue