Merge VNEXT into Main (#464)

* [VNEXT] feat: Multi-DB type support (#291)

* feat: Multi-DB type URL formats and config

* fix: remove legacy sqlite path config and minor other things

* fix: dumb eslint issues

* fix: dumb eslint issues

* fix: application can be tested with sqlite

* fix: minor config formatting

* chore: some cleanup

* feat: postgres migration creation now works

The migration creation for postgres now works properly.
Removed MySQL support, having too many issues with it at this time.

* chore: revert some strings back to bytes as they should be

* feat: improve languages support

* feat: add locale time ago formatting and the local name for the language in language dropdown

* Update FUNDING.yml

* chore: remove some more mysql stuff

* fix: coderabbit security recommendations

* fix: validate postgres sslmode

* Update migrations.go

* fix: postgres migration creation now works

* fix: errors in raw sql queries

* fix: lint error, and simpler SQL query

* fix: migrations directory string

* fix: stats related test

* fix: sql query

* Update TextArea.vue

* Update TextField.vue

* chore: run integration testing on multiple postgresql versions

* chore: jobs should run for vnext branch PRs

* fix: missed $ for Postgres testing

* fix: environment variable for db ssl mode

* fix: lint issue from a merge

* chore: trying to fix postgresql testing

* chore: trying to fix postgresql testing

* fix: trying to fix postgresql testing

* fix: trying to fix postgresql testing

---------

Co-authored-by: tonya <tonya@tokia.dev>

* fix: publish docker vnext branch

* Add upgrade guide documentation

* chore: add new config options to documentation

* Update vnext (#314)

* feat: make 404 follow theme and add a return home page

* feat: sanitise translations when using v-html

* chore: Add native API docs to website

* chore: remove try it button from api docs

---------

Co-authored-by: tonyaellie <tonya@tokia.dev>

* Update Dockerfile

Update dockerfile to test the theory of data folder breaking in vnext

* fix: broken docker image

* fix: statistics

* feat: support mm, cm and inches for label generation

* [VNEXT] feat: Multi-DB type support (#291)

* feat: Multi-DB type URL formats and config

* fix: remove legacy sqlite path config and minor other things

* fix: dumb eslint issues

* fix: dumb eslint issues

* fix: application can be tested with sqlite

* fix: minor config formatting

* chore: some cleanup

* feat: postgres migration creation now works

The migration creation for postgres now works properly.
Removed MySQL support, having too many issues with it at this time.

* chore: revert some strings back to bytes as they should be

* feat: improve languages support

* feat: add locale time ago formatting and the local name for the language in language dropdown

* Update FUNDING.yml

* chore: remove some more mysql stuff

* fix: coderabbit security recommendations

* fix: validate postgres sslmode

* Update migrations.go

* fix: postgres migration creation now works

* fix: errors in raw sql queries

* fix: lint error, and simpler SQL query

* fix: migrations directory string

* fix: stats related test

* fix: sql query

* Update TextArea.vue

* Update TextField.vue

* chore: run integration testing on multiple postgresql versions

* chore: jobs should run for vnext branch PRs

* fix: missed $ for Postgres testing

* fix: environment variable for db ssl mode

* fix: lint issue from a merge

* chore: trying to fix postgresql testing

* chore: trying to fix postgresql testing

* fix: trying to fix postgresql testing

* fix: trying to fix postgresql testing

---------

Co-authored-by: tonya <tonya@tokia.dev>

* fix: publish docker vnext branch

* Add upgrade guide documentation

* chore: add new config options to documentation

* Update Dockerfile

Update dockerfile to test the theory of data folder breaking in vnext

* fix: broken docker image

* fix: statistics

* feat: support mm, cm and inches for label generation

* Update go dependencies

* Update documentation

* Slight update to docker actions

* Small doc update

* More doc changes

* Sort out migrations

* Temp fix to broken stats test

* Update dependencies

* Update documentation

* Fix broken merge

* Fix docker image sqlite path

* Fix minor taskfile issue

---------

Co-authored-by: tonya <tonya@tokia.dev>
Co-authored-by: Katos <7927609+katosdev@users.noreply.github.com>
This commit is contained in:
Matt Kilgore
2025-03-04 08:16:17 -05:00
committed by GitHub
parent 33ecc49ad7
commit 3a3280466e
52 changed files with 3050 additions and 2592 deletions

View File

@@ -4,9 +4,11 @@ import (
"bytes"
"context"
"fmt"
"github.com/google/uuid"
"net/http"
"os"
"path/filepath"
"strings"
"time"
atlas "ariga.io/atlas/sql/migrate"
@@ -28,6 +30,7 @@ import (
"github.com/sysadminsmedia/homebox/backend/internal/sys/config"
"github.com/sysadminsmedia/homebox/backend/internal/web/mid"
_ "github.com/lib/pq"
_ "github.com/sysadminsmedia/homebox/backend/pkgs/cgofreesqlite"
)
@@ -46,15 +49,29 @@ func build() string {
return fmt.Sprintf("%s, commit %s, built at %s", version, short, buildTime)
}
// @title Homebox API
// @version 1.0
// @description Track, Manage, and Organize your Things.
// @contact.name Don't
// @BasePath /api
// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization
// @description "Type 'Bearer TOKEN' to correctly set the API Key"
func validatePostgresSSLMode(sslMode string) bool {
validModes := map[string]bool{
"": true,
"disable": true,
"allow": true,
"prefer": true,
"require": true,
"verify-ca": true,
"verify-full": true,
}
return validModes[strings.ToLower(strings.TrimSpace(sslMode))]
}
// @title Homebox API
// @version 1.0
// @description Track, Manage, and Organize your Things.
// @contact.name Don't
// @BasePath /api
// @securityDefinitions.apikey Bearer
// @in header
// @name Authorization
// @description "Type 'Bearer TOKEN' to correctly set the API Key"
func main() {
zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack
@@ -80,13 +97,32 @@ func run(cfg *config.Config) error {
log.Fatal().Err(err).Msg("failed to create data directory")
}
c, err := ent.Open("sqlite3", cfg.Storage.SqliteURL)
if strings.ToLower(cfg.Database.Driver) == "postgres" {
if !validatePostgresSSLMode(cfg.Database.SslMode) {
log.Fatal().Str("sslmode", cfg.Database.SslMode).Msg("invalid sslmode")
}
}
// Set up the database URL based on the driver because for some reason a common URL format is not used
databaseURL := ""
switch strings.ToLower(cfg.Database.Driver) {
case "sqlite3":
databaseURL = cfg.Database.SqlitePath
case "postgres":
databaseURL = fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", cfg.Database.Host, cfg.Database.Port, cfg.Database.Username, cfg.Database.Password, cfg.Database.Database, cfg.Database.SslMode)
default:
log.Fatal().Str("driver", cfg.Database.Driver).Msg("unsupported database driver")
}
c, err := ent.Open(strings.ToLower(cfg.Database.Driver), databaseURL)
if err != nil {
log.Fatal().
Err(err).
Str("driver", "sqlite").
Str("url", cfg.Storage.SqliteURL).
Msg("failed opening connection to sqlite")
Str("driver", strings.ToLower(cfg.Database.Driver)).
Str("host", cfg.Database.Host).
Str("port", cfg.Database.Port).
Str("database", cfg.Database.Database).
Msg("failed opening connection to {driver} database at {host}:{port}/{database}")
}
defer func(c *ent.Client) {
err := c.Close()
@@ -95,9 +131,14 @@ func run(cfg *config.Config) error {
}
}(c)
temp := filepath.Join(os.TempDir(), "migrations")
// Always create a random temporary directory for migrations
tempUUID, err := uuid.NewUUID()
if err != nil {
return err
}
temp := filepath.Join(os.TempDir(), fmt.Sprintf("homebox-%s", tempUUID.String()))
err = migrations.Write(temp)
err = migrations.Write(temp, cfg.Database.Driver)
if err != nil {
return err
}
@@ -117,17 +158,18 @@ func run(cfg *config.Config) error {
if err != nil {
log.Error().
Err(err).
Str("driver", "sqlite").
Str("url", cfg.Storage.SqliteURL).
Str("driver", cfg.Database.Driver).
Str("url", databaseURL).
Msg("failed creating schema resources")
return err
}
err = os.RemoveAll(temp)
if err != nil {
log.Error().Err(err).Msg("failed to remove temporary directory for database migrations")
return err
}
defer func() {
err := os.RemoveAll(temp)
if err != nil {
log.Error().Err(err).Msg("failed to remove temporary directory for database migrations")
}
}()
collectFuncs := []currencies.CollectorFunc{
currencies.CollectDefaults(),