mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Disable AI features on non-new installations upgrading to 4.51.X (#19482)
#19365 Assuming we release this fix in 4.51.0: - Migration from a version without the feature (< 4.50.0) to 4.51.0: Should disable (set `ai_features_disabled=true`). - Migration from a version with the feature (>= 4.50.X < 4.51.0) to 4.51.0: Should keep `ai_features_disabled` as-is. - New installation of Fleet: Should come with AI features enabled (`ai_features_disabled=false`). From https://github.com/fleetdm/fleet/issues/19365#issuecomment-2145825363. - [X] Changes file added for user-visible changes in `changes/`, `orbit/changes/` or `ee/fleetd-chrome/changes`. See [Changes files](https://fleetdm.com/docs/contributing/committing-changes#changes-files) for more information. - [X] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [X] Manual QA for all new/changed functionality
This commit is contained in:
parent
3e19cd90a9
commit
5f65ea831c
2 changed files with 65 additions and 0 deletions
1
changes/19365-disable-ai-migration
Normal file
1
changes/19365-disable-ai-migration
Normal file
|
|
@ -0,0 +1 @@
|
|||
* Disabled AI features on non-new installations upgrading from < 4.50.X to >= 4.51.X.
|
||||
|
|
@ -2,7 +2,10 @@ package tables
|
|||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
|
@ -22,6 +25,67 @@ func Up_20240430111727(tx *sql.Tx) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("failed to delete query_results %w", err)
|
||||
}
|
||||
|
||||
//
|
||||
// The following "fix" was introduced after this migration was released in 4.50.0.
|
||||
// We are adding it here to disable the AI features (set ai_features_disabled=true)
|
||||
// for non-new installations that are upgrading from < 4.50.0 using the new version
|
||||
// of this migration to be released in 4.51.X.
|
||||
//
|
||||
if err := fixDisableAIForNonNewInstallation(tx); err != nil {
|
||||
return fmt.Errorf("failed to update ai_features_disabled: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func fixDisableAIForNonNewInstallation(tx *sql.Tx) error {
|
||||
var usersCount int
|
||||
row := tx.QueryRow(`SELECT COUNT(*) FROM users;`)
|
||||
if err := row.Scan(&usersCount); err != nil {
|
||||
return fmt.Errorf("select count users: %w", err)
|
||||
}
|
||||
if usersCount == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
//
|
||||
// At least a "setup" user was configured,
|
||||
// thus we assume this is not a new installation.
|
||||
//
|
||||
|
||||
var raw json.RawMessage
|
||||
row = tx.QueryRow(`SELECT json_value FROM app_config_json LIMIT 1;`)
|
||||
if err := row.Scan(&raw); err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("select app_config_json: %w", err)
|
||||
}
|
||||
|
||||
var config map[string]interface{}
|
||||
if err := json.Unmarshal(raw, &config); err != nil {
|
||||
return fmt.Errorf("unmarshal appconfig: %w", err)
|
||||
}
|
||||
|
||||
ss, ok := config["server_settings"]
|
||||
if !ok {
|
||||
return errors.New("missing server_settings")
|
||||
}
|
||||
serverSettings, ok := ss.(map[string]interface{})
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid type for server_settings: %T", ss)
|
||||
}
|
||||
serverSettings["ai_features_disabled"] = true
|
||||
|
||||
b, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("marshal updated appconfig: %w", err)
|
||||
}
|
||||
if _, err := tx.Exec(`UPDATE app_config_json SET json_value = ? WHERE id = 1;`, b); err != nil {
|
||||
return fmt.Errorf("update app_config_json: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue