Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring common mysql #26367

Merged
merged 70 commits into from
Feb 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
1dda21f
Added feature migrations
getvictor Jan 24, 2025
d42de45
Add feature schema.sql, and fix linting errors.
getvictor Jan 24, 2025
88db932
Setting up android directories.
getvictor Jan 24, 2025
e7c4263
WIP
getvictor Jan 27, 2025
534d50e
Temporarily skipping failing test.
getvictor Jan 28, 2025
a52b3e3
Hooked up DB for android enteprises.
getvictor Jan 28, 2025
464fca3
WIP
getvictor Jan 28, 2025
e4bf250
Things mostly working.
getvictor Jan 29, 2025
61fe90b
Updating android schema.
getvictor Jan 29, 2025
acc0c73
Split off Android service.
getvictor Jan 30, 2025
16be7ef
Added devices.delete to tools/android
getvictor Jan 30, 2025
1614233
Added architecture test.
getvictor Jan 31, 2025
655a44d
Minor cleanup.
getvictor Feb 3, 2025
0cb3c92
Merge remote-tracking branch 'origin/main' into victor/android-poc
getvictor Feb 5, 2025
ac001b5
Improved arch_test.go
getvictor Feb 7, 2025
9ac4983
Improved archtest
getvictor Feb 9, 2025
7c43db3
Merge remote-tracking branch 'origin/main' into victor/android-poc
getvictor Feb 9, 2025
29b39e8
Applied refactorings from main.
getvictor Feb 10, 2025
fe58e34
Minor fixes
getvictor Feb 10, 2025
759c08f
Merge remote-tracking branch 'origin/victor/android-poc' into victor/…
getvictor Feb 11, 2025
5b4c3de
WIP preparing for real Android implementation
getvictor Feb 11, 2025
5a61ea4
Merge remote-tracking branch 'origin/main' into victor/26218-android-…
getvictor Feb 11, 2025
35d9fde
Refactoring
getvictor Feb 11, 2025
a47516e
Refactoring
getvictor Feb 11, 2025
3d93714
Refactoring, still
getvictor Feb 11, 2025
caaa56f
Refactoring, still
getvictor Feb 11, 2025
e1471d4
Refactoring, done?
getvictor Feb 11, 2025
f79f67f
Cleanup
getvictor Feb 11, 2025
0b041d9
Removed AndroidCron const.
getvictor Feb 12, 2025
0f916e2
Fix issues in manual testing.
getvictor Feb 12, 2025
e9b6d11
Added signup_url
getvictor Feb 12, 2025
0ddc271
Added basic connect functionality. Does not return HTML page at this …
getvictor Feb 12, 2025
abfa94b
Fixes and start work on deleting enterprise.
getvictor Feb 12, 2025
b11d5ff
Update appConfig cloner.
getvictor Feb 12, 2025
4d1f723
Rolling back migration-related split.
getvictor Feb 13, 2025
7235ab4
Add an empty line
getvictor Feb 13, 2025
e7b18da
Moved android package under MDM
getvictor Feb 13, 2025
5f06d46
Merge remote-tracking branch 'origin/main' into victor/26218-android-…
getvictor Feb 13, 2025
00f5acb
Fixing issues
getvictor Feb 13, 2025
8f4c8ef
Cleanup
getvictor Feb 13, 2025
f7e2b00
Moved routes type.
getvictor Feb 13, 2025
cefd330
Merge remote-tracking branch 'origin/victor/26218-android-turn-on' in…
getvictor Feb 13, 2025
0b9a70b
Fixing up the merge.
getvictor Feb 13, 2025
e41516b
Cleanup
getvictor Feb 13, 2025
9e4b912
Finished delete enterprise functionality.
getvictor Feb 13, 2025
0e09daf
Merge remote-tracking branch 'origin/main' into victor/26218-basic-fu…
getvictor Feb 13, 2025
a662600
Merge to main fixes.
getvictor Feb 13, 2025
eb3b2dc
Fixes after manual testing.
getvictor Feb 13, 2025
df0c94f
Merge remote-tracking branch 'origin/main' into victor/26218-basic-fu…
getvictor Feb 14, 2025
832496e
Fix merge from main.
getvictor Feb 14, 2025
69f6e0a
Refactoring.
getvictor Feb 13, 2025
cacb363
Refactoring.
getvictor Feb 13, 2025
647d4ae
Using generics in endpoint_utils
getvictor Feb 14, 2025
d8e1350
Fixing test
getvictor Feb 14, 2025
9c7d78a
Public Errorer and move
getvictor Feb 14, 2025
06abfb0
service/Service done?
getvictor Feb 14, 2025
fb6fd09
Fix compile issue.
getvictor Feb 14, 2025
275c77c
Done?
getvictor Feb 14, 2025
e42b3fd
Cleanup
getvictor Feb 15, 2025
3f0d0a3
Renamed endpoint_utils to eu
getvictor Feb 15, 2025
12c33e8
Comment cleanup
getvictor Feb 15, 2025
1f435ee
Refactoring common mysql
getvictor Feb 14, 2025
bc7e74e
Refactoring.
getvictor Feb 15, 2025
6b28749
Refactoring
getvictor Feb 15, 2025
7e49451
Fixed test
getvictor Feb 15, 2025
2a943ad
Refactoring
getvictor Feb 16, 2025
3f5ba4a
Finished?
getvictor Feb 16, 2025
c394960
Fixing test
getvictor Feb 16, 2025
15f4801
Removed `ctu` in enterprises_test.go
getvictor Feb 17, 2025
fa3251d
Merge remote-tracking branch 'origin/main' into victor/26218-refactor…
getvictor Feb 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions server/datastore/mysql/apple_mdm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (

"github.com/VividCortex/mysqlerr"
"github.com/fleetdm/fleet/v4/pkg/optjson"
"github.com/fleetdm/fleet/v4/server/datastore/mysql/common_mysql"
"github.com/fleetdm/fleet/v4/server/datastore/s3"
"github.com/fleetdm/fleet/v4/server/fleet"
fleetmdm "github.com/fleetdm/fleet/v4/server/mdm"
Expand Down Expand Up @@ -4650,7 +4651,7 @@ func testMDMAppleResetEnrollment(t *testing.T, ds *Datastore) {
// host has no boostrap package command yet
_, err = ds.GetHostBootstrapPackageCommand(ctx, host.UUID)
require.Error(t, err)
nfe := &notFoundError{}
nfe := &common_mysql.NotFoundError{}
require.ErrorAs(t, err, &nfe)

err = ds.RecordHostBootstrapPackage(ctx, "command-uuid", host.UUID)
Expand Down Expand Up @@ -5560,7 +5561,7 @@ func TestRestorePendingDEPHost(t *testing.T) {
require.Equal(t, expectedHost.Platform, h.Platform)
require.Equal(t, expectedHost.TeamID, h.TeamID)
} else {
nfe := &notFoundError{}
nfe := &common_mysql.NotFoundError{}
require.ErrorAs(t, err, &nfe)
}

Expand Down
141 changes: 141 additions & 0 deletions server/datastore/mysql/common_mysql/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package common_mysql

import (
"context"
"database/sql"
"fmt"
"net/url"
"time"

"github.com/fleetdm/fleet/v4/server/config"
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/go-kit/log"
"github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
"github.com/ngrok/sqlmw"
)

type DBOptions struct {
// MaxAttempts configures the number of retries to connect to the DB
MaxAttempts int
Logger log.Logger
ReplicaConfig *config.MysqlConfig
Interceptor sqlmw.Interceptor
TracingConfig *config.LoggingConfig
MinLastOpenedAtDiff time.Duration
SqlMode string
PrivateKey string
}

func NewDB(conf *config.MysqlConfig, opts *DBOptions, otelDriverName string) (*sqlx.DB, error) {
driverName := "mysql"
if opts.TracingConfig != nil && opts.TracingConfig.TracingEnabled {
if opts.TracingConfig.TracingType == "opentelemetry" {
driverName = otelDriverName
} else {
driverName = "apm/mysql"
}
}
if opts.Interceptor != nil {
driverName = "mysql-mw"
sql.Register(driverName, sqlmw.Driver(mysql.MySQLDriver{}, opts.Interceptor))
}
if opts.SqlMode != "" {
conf.SQLMode = opts.SqlMode
}

dsn := generateMysqlConnectionString(*conf)
db, err := sqlx.Open(driverName, dsn)
if err != nil {
return nil, err
}

db.SetMaxIdleConns(conf.MaxIdleConns)
db.SetMaxOpenConns(conf.MaxOpenConns)
db.SetConnMaxLifetime(time.Second * time.Duration(conf.ConnMaxLifetime))

var dbError error
for attempt := 0; attempt < opts.MaxAttempts; attempt++ {
dbError = db.Ping()
if dbError == nil {
// we're connected!
break
}
interval := time.Duration(attempt) * time.Second
opts.Logger.Log("mysql", fmt.Sprintf(
"could not connect to db: %v, sleeping %v", dbError, interval))
time.Sleep(interval)
}

if dbError != nil {
return nil, dbError
}
return db, nil
}

// generateMysqlConnectionString returns a MySQL connection string using the
// provided configuration.
func generateMysqlConnectionString(conf config.MysqlConfig) string {
params := url.Values{
// using collation implicitly sets the charset too
// and it's the recommended way to do it per the
// driver documentation:
// https://github.com/go-sql-driver/mysql#charset
"collation": []string{"utf8mb4_unicode_ci"},
"parseTime": []string{"true"},
"loc": []string{"UTC"},
"time_zone": []string{"'-00:00'"},
"clientFoundRows": []string{"true"},
"allowNativePasswords": []string{"true"},
"group_concat_max_len": []string{"4194304"},
"multiStatements": []string{"true"},
}
if conf.TLSConfig != "" {
params.Set("tls", conf.TLSConfig)
}
if conf.SQLMode != "" {
params.Set("sql_mode", conf.SQLMode)
}

dsn := fmt.Sprintf(
"%s:%s@%s(%s)/%s?%s",
conf.Username,
conf.Password,
conf.Protocol,
conf.Address,
conf.Database,
params.Encode(),
)

return dsn
}

func WithTxx(ctx context.Context, db *sqlx.DB, fn TxFn, logger log.Logger) error {
tx, err := db.BeginTxx(ctx, nil)
if err != nil {
return ctxerr.Wrap(ctx, err, "create transaction")
}

defer func() {
if p := recover(); p != nil {
if err := tx.Rollback(); err != nil {
logger.Log("err", err, "msg", "error encountered during transaction panic rollback")
}
panic(p)
}
}()

if err := fn(tx); err != nil {
rbErr := tx.Rollback()
if rbErr != nil && rbErr != sql.ErrTxDone {
return ctxerr.Wrapf(ctx, err, "got err '%s' rolling back after err", rbErr.Error())
}
return err
}

if err := tx.Commit(); err != nil {
return ctxerr.Wrap(ctx, err, "commit transaction")
}

return nil
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
package mysql

// TODO(26218): Refactor this to common_mysql
package common_mysql

import (
"database/sql"
"fmt"

"github.com/fleetdm/fleet/v4/server/fleet"
)

type notFoundError struct {
type NotFoundError struct {
ID uint
Name string
Message string
ResourceType string
}

func notFound(kind string) *notFoundError {
return &notFoundError{
// Compile-time interface check.
var _ fleet.NotFoundError = &NotFoundError{}

func NotFound(kind string) *NotFoundError {
return &NotFoundError{
ResourceType: kind,
}
}

func (e *notFoundError) Error() string {
func (e *NotFoundError) Error() string {
if e.ID != 0 {
return fmt.Sprintf("%s %d was not found in the datastore", e.ResourceType, e.ID)
}
Expand All @@ -33,28 +36,28 @@ func (e *notFoundError) Error() string {
return fmt.Sprintf("%s was not found in the datastore", e.ResourceType)
}

func (e *notFoundError) WithID(id uint) error {
func (e *NotFoundError) WithID(id uint) error {
e.ID = id
return e
}

func (e *notFoundError) WithName(name string) error {
func (e *NotFoundError) WithName(name string) error {
e.Name = name
return e
}

func (e *notFoundError) WithMessage(msg string) error {
func (e *NotFoundError) WithMessage(msg string) error {
e.Message = msg
return e
}

func (e *notFoundError) IsNotFound() bool {
func (e *NotFoundError) IsNotFound() bool {
return true
}

// Is helps so that errors.Is(err, sql.ErrNoRows) returns true for an
// error of type *notFoundError, without having to wrap sql.ErrNoRows
// error of type *NotFoundError, without having to wrap sql.ErrNoRows
// explicitly.
func (e *notFoundError) Is(other error) bool {
func (e *NotFoundError) Is(other error) bool {
return other == sql.ErrNoRows
}
Loading
Loading