5 Commits

Author SHA1 Message Date
Pijus Kamandulis
e080888c20 Add shared-libraries to release 2025-01-28 23:28:23 +02:00
Pijus Kamandulis
b8d79fd945 Upgrade upload-artifact pipeline action 2025-01-28 21:31:05 +02:00
Pijus Kamandulis
f25cb7fb03 Stamp binaries with version control information 2025-01-28 21:15:49 +02:00
Pijus Kamandulis
125f10d8a2 Add more error handling and mutex guards 2025-01-27 21:09:37 +02:00
Pijus Kamandulis
d6b816b55a Fix docker tag 2025-01-25 21:17:32 +02:00
12 changed files with 106 additions and 35 deletions

View File

@@ -22,9 +22,10 @@ jobs:
targets: linux/amd64,linux/arm64,windows/amd64,windows/arm64,darwin/amd64,darwin/arm64 targets: linux/amd64,linux/arm64,windows/amd64,windows/arm64,darwin/amd64,darwin/arm64
v: true v: true
buildmode: c-shared buildmode: c-shared
buildvcs: true
- name: Upload artifact - name: Upload artifact
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: shared-libraries name: shared-libraries
path: dist/* path: dist/*

View File

@@ -17,16 +17,32 @@ jobs:
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up Go - name: Set up Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: 1.22.0 go-version: 1.22.0
- name: Cross-Compile with xgo
uses: crazy-max/ghaction-xgo@v3.1.0
with:
xgo_version: latest
go_version: 1.22.0
dest: sharedlibrary_dist
pkg: sharedlibrary
prefix: cosmium
targets: linux/amd64,linux/arm64,windows/amd64,windows/arm64,darwin/amd64,darwin/arm64
v: true
buildmode: c-shared
buildvcs: true
- name: Docker Login - name: Docker Login
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: ghcr.io registry: ghcr.io
username: ${{ github.actor }} username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} password: ${{ secrets.GITHUB_TOKEN }}
- name: Run GoReleaser - name: Run GoReleaser
uses: goreleaser/goreleaser-action@v5 uses: goreleaser/goreleaser-action@v5
with: with:

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
dist/ dist/
sharedlibrary_dist/
ignored/ ignored/
explorer_www/ explorer_www/
main main

View File

@@ -26,6 +26,23 @@ brews:
commit_author: commit_author:
name: pikami name: pikami
email: git@pikami.org email: git@pikami.org
skip_upload: auto
archives:
- id: bundle
format: tar.gz
format_overrides:
- goos: windows
format: zip
- id: shared-libraries
meta: true
format: "tar.gz"
wrap_in_directory: true
name_template: "{{ .ProjectName }}_{{ .Version }}_shared-libraries"
files:
- LICENSE
- README.md
- sharedlibrary_dist/**
dockers: dockers:
- id: docker-linux-amd64 - id: docker-linux-amd64
@@ -33,7 +50,6 @@ dockers:
goarch: amd64 goarch: amd64
image_templates: image_templates:
- "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-amd64" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-amd64"
- "ghcr.io/pikami/{{ .ProjectName }}:latest-amd64"
dockerfile: Dockerfile dockerfile: Dockerfile
use: buildx use: buildx
build_flag_templates: build_flag_templates:
@@ -51,9 +67,7 @@ dockers:
goarch: arm64 goarch: arm64
image_templates: image_templates:
- "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-arm64" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-arm64"
- "ghcr.io/pikami/{{ .ProjectName }}:latest-arm64"
- "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-arm64v8" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-arm64v8"
- "ghcr.io/pikami/{{ .ProjectName }}:latest-arm64v8"
dockerfile: Dockerfile dockerfile: Dockerfile
use: buildx use: buildx
build_flag_templates: build_flag_templates:
@@ -71,7 +85,7 @@ dockers:
goarch: amd64 goarch: amd64
image_templates: image_templates:
- "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-explorer-amd64" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-explorer-amd64"
dockerfile: Dockerfile dockerfile: Explorer.Dockerfile
use: buildx use: buildx
build_flag_templates: build_flag_templates:
- "--platform=linux/amd64" - "--platform=linux/amd64"
@@ -89,7 +103,7 @@ dockers:
image_templates: image_templates:
- "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-explorer-arm64" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-explorer-arm64"
- "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-explorer-arm64v8" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-explorer-arm64v8"
dockerfile: Dockerfile dockerfile: Explorer.Dockerfile
use: buildx use: buildx
build_flag_templates: build_flag_templates:
- "--platform=linux/arm64" - "--platform=linux/arm64"
@@ -104,16 +118,19 @@ dockers:
docker_manifests: docker_manifests:
- name_template: 'ghcr.io/pikami/{{ .ProjectName }}:latest' - name_template: 'ghcr.io/pikami/{{ .ProjectName }}:latest'
skip_push: auto
image_templates: image_templates:
- "ghcr.io/pikami/{{ .ProjectName }}:latest-amd64" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-amd64"
- "ghcr.io/pikami/{{ .ProjectName }}:latest-arm64" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-arm64"
- "ghcr.io/pikami/{{ .ProjectName }}:latest-arm64v8" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-arm64v8"
- name_template: 'ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}' - name_template: 'ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}'
skip_push: auto
image_templates: image_templates:
- "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-amd64" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-amd64"
- "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-arm64" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-arm64"
- "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-arm64v8" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-arm64v8"
- name_template: 'ghcr.io/pikami/{{ .ProjectName }}:explorer' - name_template: 'ghcr.io/pikami/{{ .ProjectName }}:explorer'
skip_push: auto
image_templates: image_templates:
- "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-explorer-amd64" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-explorer-amd64"
- "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-explorer-arm64" - "ghcr.io/pikami/{{ .ProjectName }}:{{ .Version }}-explorer-arm64"

View File

@@ -58,15 +58,15 @@ func (c *ServerConfig) PopulateCalculatedFields() {
switch c.LogLevel { switch c.LogLevel {
case "debug": case "debug":
logger.LogLevel = logger.LogLevelDebug logger.SetLogLevel(logger.LogLevelDebug)
case "info": case "info":
logger.LogLevel = logger.LogLevelInfo logger.SetLogLevel(logger.LogLevelInfo)
case "error": case "error":
logger.LogLevel = logger.LogLevelError logger.SetLogLevel(logger.LogLevelError)
case "silent": case "silent":
logger.LogLevel = logger.LogLevelSilent logger.SetLogLevel(logger.LogLevelSilent)
default: default:
logger.LogLevel = logger.LogLevelInfo logger.SetLogLevel(logger.LogLevelInfo)
} }
} }

View File

@@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"net/http" "net/http"
"sync"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/pikami/cosmium/api/handlers" "github.com/pikami/cosmium/api/handlers"
@@ -13,15 +14,19 @@ import (
tlsprovider "github.com/pikami/cosmium/internal/tls_provider" tlsprovider "github.com/pikami/cosmium/internal/tls_provider"
) )
var ginMux sync.Mutex
func (s *ApiServer) CreateRouter(repository *repositories.DataRepository) { func (s *ApiServer) CreateRouter(repository *repositories.DataRepository) {
routeHandlers := handlers.NewHandlers(repository, s.config) routeHandlers := handlers.NewHandlers(repository, s.config)
ginMux.Lock()
gin.DefaultWriter = logger.InfoWriter() gin.DefaultWriter = logger.InfoWriter()
gin.DefaultErrorWriter = logger.ErrorWriter() gin.DefaultErrorWriter = logger.ErrorWriter()
if s.config.LogLevel != "debug" { if s.config.LogLevel != "debug" {
gin.SetMode(gin.ReleaseMode) gin.SetMode(gin.ReleaseMode)
} }
ginMux.Unlock()
router := gin.Default(func(e *gin.Engine) { router := gin.Default(func(e *gin.Engine) {
e.RedirectTrailingSlash = false e.RedirectTrailingSlash = false

View File

@@ -6,6 +6,7 @@ import (
"os" "os"
"runtime" "runtime"
"strings" "strings"
"sync"
) )
type LogLevelType int type LogLevelType int
@@ -21,67 +22,68 @@ type LogWriter struct {
WriterLevel LogLevelType WriterLevel LogLevelType
} }
var LogLevel = LogLevelInfo var logLevelMutex sync.RWMutex
var logLevel = LogLevelInfo
var DebugLogger = log.New(os.Stdout, "", log.Ldate|log.Ltime) var DebugLogger = log.New(os.Stdout, "", log.Ldate|log.Ltime)
var InfoLogger = log.New(os.Stdout, "", log.Ldate|log.Ltime) var InfoLogger = log.New(os.Stdout, "", log.Ldate|log.Ltime)
var ErrorLogger = log.New(os.Stderr, "", log.Ldate|log.Ltime) var ErrorLogger = log.New(os.Stderr, "", log.Ldate|log.Ltime)
func DebugLn(v ...any) { func DebugLn(v ...any) {
if LogLevel <= LogLevelDebug { if GetLogLevel() <= LogLevelDebug {
prefix := getCallerPrefix() prefix := getCallerPrefix()
DebugLogger.Println(append([]interface{}{prefix}, v...)...) DebugLogger.Println(append([]interface{}{prefix}, v...)...)
} }
} }
func Debug(v ...any) { func Debug(v ...any) {
if LogLevel <= LogLevelDebug { if GetLogLevel() <= LogLevelDebug {
prefix := getCallerPrefix() prefix := getCallerPrefix()
DebugLogger.Println(append([]interface{}{prefix}, v...)...) DebugLogger.Println(append([]interface{}{prefix}, v...)...)
} }
} }
func Debugf(format string, v ...any) { func Debugf(format string, v ...any) {
if LogLevel <= LogLevelDebug { if GetLogLevel() <= LogLevelDebug {
prefix := getCallerPrefix() prefix := getCallerPrefix()
DebugLogger.Printf(prefix+format, v...) DebugLogger.Printf(prefix+format, v...)
} }
} }
func InfoLn(v ...any) { func InfoLn(v ...any) {
if LogLevel <= LogLevelInfo { if GetLogLevel() <= LogLevelInfo {
InfoLogger.Println(v...) InfoLogger.Println(v...)
} }
} }
func Info(v ...any) { func Info(v ...any) {
if LogLevel <= LogLevelInfo { if GetLogLevel() <= LogLevelInfo {
InfoLogger.Print(v...) InfoLogger.Print(v...)
} }
} }
func Infof(format string, v ...any) { func Infof(format string, v ...any) {
if LogLevel <= LogLevelInfo { if GetLogLevel() <= LogLevelInfo {
InfoLogger.Printf(format, v...) InfoLogger.Printf(format, v...)
} }
} }
func ErrorLn(v ...any) { func ErrorLn(v ...any) {
if LogLevel <= LogLevelError { if GetLogLevel() <= LogLevelError {
prefix := getCallerPrefix() prefix := getCallerPrefix()
ErrorLogger.Println(append([]interface{}{prefix}, v...)...) ErrorLogger.Println(append([]interface{}{prefix}, v...)...)
} }
} }
func Error(v ...any) { func Error(v ...any) {
if LogLevel <= LogLevelError { if GetLogLevel() <= LogLevelError {
prefix := getCallerPrefix() prefix := getCallerPrefix()
ErrorLogger.Print(append([]interface{}{prefix}, v...)...) ErrorLogger.Print(append([]interface{}{prefix}, v...)...)
} }
} }
func Errorf(format string, v ...any) { func Errorf(format string, v ...any) {
if LogLevel <= LogLevelError { if GetLogLevel() <= LogLevelError {
prefix := getCallerPrefix() prefix := getCallerPrefix()
ErrorLogger.Printf(prefix+format, v...) ErrorLogger.Printf(prefix+format, v...)
} }
@@ -112,11 +114,25 @@ func DebugWriter() *LogWriter {
return &LogWriter{WriterLevel: LogLevelDebug} return &LogWriter{WriterLevel: LogLevelDebug}
} }
func SetLogLevel(level LogLevelType) {
logLevelMutex.Lock()
defer logLevelMutex.Unlock()
logLevel = level
}
func GetLogLevel() LogLevelType {
logLevelMutex.RLock()
defer logLevelMutex.RUnlock()
return logLevel
}
func getCallerPrefix() string { func getCallerPrefix() string {
_, file, line, ok := runtime.Caller(2) _, file, line, ok := runtime.Caller(2)
if ok { if ok {
parts := strings.Split(file, "/") parts := strings.Split(file, "/")
file = parts[len(parts)-1] if len(parts) > 0 {
file = parts[len(parts)-1]
}
return fmt.Sprintf("%s:%d - ", file, line) return fmt.Sprintf("%s:%d - ", file, line)
} }

View File

@@ -46,8 +46,8 @@ func (r *DataRepository) LoadStateFS(filePath string) {
} }
func (r *DataRepository) LoadStateJSON(jsonData string) error { func (r *DataRepository) LoadStateJSON(jsonData string) error {
r.storeState.RLock() r.storeState.Lock()
defer r.storeState.RUnlock() defer r.storeState.Unlock()
var state repositorymodels.State var state repositorymodels.State
if err := json.Unmarshal([]byte(jsonData), &state); err != nil { if err := json.Unmarshal([]byte(jsonData), &state); err != nil {

View File

@@ -47,7 +47,10 @@ func GetCollection(serverName *C.char, databaseId *C.char, collectionId *C.char)
return C.CString("") return C.CString("")
} }
collectionJson, _ := json.Marshal(collection) collectionJson, err := json.Marshal(collection)
if err != nil {
return C.CString("")
}
return C.CString(string(collectionJson)) return C.CString(string(collectionJson))
} }
@@ -67,7 +70,10 @@ func GetAllCollections(serverName *C.char, databaseId *C.char) *C.char {
return C.CString("") return C.CString("")
} }
collectionsJson, _ := json.Marshal(collections) collectionsJson, err := json.Marshal(collections)
if err != nil {
return C.CString("")
}
return C.CString(string(collectionsJson)) return C.CString(string(collectionsJson))
} }

View File

@@ -45,7 +45,10 @@ func GetDatabase(serverName *C.char, databaseId *C.char) *C.char {
return C.CString("") return C.CString("")
} }
databaseJson, _ := json.Marshal(database) databaseJson, err := json.Marshal(database)
if err != nil {
return C.CString("")
}
return C.CString(string(databaseJson)) return C.CString(string(databaseJson))
} }

View File

@@ -49,7 +49,10 @@ func GetDocument(serverName *C.char, databaseId *C.char, collectionId *C.char, d
return C.CString("") return C.CString("")
} }
documentJson, _ := json.Marshal(document) documentJson, err := json.Marshal(document)
if err != nil {
return C.CString("")
}
return C.CString(string(documentJson)) return C.CString(string(documentJson))
} }
@@ -70,7 +73,10 @@ func GetAllDocuments(serverName *C.char, databaseId *C.char, collectionId *C.cha
return C.CString("") return C.CString("")
} }
documentsJson, _ := json.Marshal(documents) documentsJson, err := json.Marshal(documents)
if err != nil {
return C.CString("")
}
return C.CString(string(documentsJson)) return C.CString(string(documentsJson))
} }

View File

@@ -14,7 +14,7 @@ type ServerInstance struct {
} }
var serverInstances map[string]*ServerInstance var serverInstances map[string]*ServerInstance
var mutex sync.RWMutex var mutex sync.Mutex
const ( const (
ResponseSuccess = 0 ResponseSuccess = 0
@@ -32,8 +32,8 @@ const (
) )
func getInstance(serverName string) (*ServerInstance, bool) { func getInstance(serverName string) (*ServerInstance, bool) {
mutex.RLock() mutex.Lock()
defer mutex.RUnlock() defer mutex.Unlock()
if serverInstances == nil { if serverInstances == nil {
serverInstances = make(map[string]*ServerInstance) serverInstances = make(map[string]*ServerInstance)