Don't overwrite FMA outputs with latest manifest if input has "frozen" set to true (#30044)
Resolves #29218. No changes file as this is internal/FMA-related. # Checklist for submitter If some of the following don't apply, delete the relevant line. <!-- Note that API documentation changes are now addressed by the product design team. --> - [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:
+19
-10
@@ -13,6 +13,7 @@ import (
|
||||
maintained_apps "github.com/fleetdm/fleet/v4/ee/maintained-apps"
|
||||
"github.com/fleetdm/fleet/v4/ee/maintained-apps/ingesters/homebrew"
|
||||
"github.com/fleetdm/fleet/v4/ee/maintained-apps/ingesters/winget"
|
||||
"github.com/fleetdm/fleet/v4/pkg/file"
|
||||
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
|
||||
kitlog "github.com/go-kit/log"
|
||||
"github.com/go-kit/log/level"
|
||||
@@ -38,8 +39,8 @@ func main() {
|
||||
"ee/maintained-apps/inputs/winget": winget.IngestApps,
|
||||
}
|
||||
|
||||
for p, i := range ingesters {
|
||||
apps, err := i(ctx, logger, p, *slugPtr)
|
||||
for inputDir, ingest := range ingesters {
|
||||
apps, err := ingest(ctx, logger, inputDir, *slugPtr)
|
||||
if err != nil {
|
||||
level.Error(logger).Log("msg", "failed to ingest apps", "error", err)
|
||||
}
|
||||
@@ -74,15 +75,23 @@ func processOutput(ctx context.Context, app *maintained_apps.FMAManifestApp) err
|
||||
return ctxerr.Wrap(ctx, err, "marshaling output app manifest")
|
||||
}
|
||||
|
||||
// Overwrite the file, since right now we're only caring about 1 version (latest). If we
|
||||
// care about previous data, it will be in our Git history.
|
||||
outPath := path.Join(maintained_apps.OutputPath, app.SlugAppName())
|
||||
outDir := path.Join(maintained_apps.OutputPath, app.SlugAppName())
|
||||
|
||||
if err := os.MkdirAll(outPath, os.ModePerm); err != nil {
|
||||
if err := os.MkdirAll(outDir, os.ModePerm); err != nil {
|
||||
return ctxerr.Wrap(ctx, err)
|
||||
}
|
||||
if err := os.WriteFile(path.Join(maintained_apps.OutputPath, fmt.Sprintf("%s.json", app.Slug)), outBytes, 0o644); err != nil {
|
||||
return ctxerr.Wrap(ctx, err, "writing output json file")
|
||||
outFilePath := path.Join(maintained_apps.OutputPath, fmt.Sprintf("%s.json", app.Slug))
|
||||
outFileExists, err := file.Exists(outFilePath)
|
||||
if err != nil {
|
||||
return ctxerr.Wrap(ctx, err, "checking if output json file exists")
|
||||
}
|
||||
|
||||
// Overwrite the file unless frozen, since right now we're only caring about 1 version (latest). If we
|
||||
// care about previous data, it will be in our Git history.
|
||||
if !app.Frozen || !outFileExists {
|
||||
if err := os.WriteFile(outFilePath, outBytes, 0o644); err != nil {
|
||||
return ctxerr.Wrap(ctx, err, "writing output json file")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -90,13 +99,13 @@ func processOutput(ctx context.Context, app *maintained_apps.FMAManifestApp) err
|
||||
|
||||
func updateAppsListFile(ctx context.Context, outApp *maintained_apps.FMAManifestApp) error {
|
||||
appListFilePath := path.Join(maintained_apps.OutputPath, "apps.json")
|
||||
file, err := os.ReadFile(appListFilePath)
|
||||
inputJson, err := os.ReadFile(appListFilePath)
|
||||
if err != nil {
|
||||
return ctxerr.Wrap(ctx, err, "reading output apps list file")
|
||||
}
|
||||
|
||||
var outputAppsFile maintained_apps.FMAListFile
|
||||
if err := json.Unmarshal(file, &outputAppsFile); err != nil {
|
||||
if err := json.Unmarshal(inputJson, &outputAppsFile); err != nil {
|
||||
return ctxerr.Wrap(ctx, err, "unmarshaling output apps list file")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
# Fleet-maintained apps (FMA)
|
||||
|
||||
## Freezing an existing app
|
||||
|
||||
Add `"frozen": true` to the appropriate input JSON file to pause automated updates to the corresponding output manifest.
|
||||
To aid in testing, manifests will still be generated for frozen inputs if the output file doesn't exist.
|
||||
|
||||
Apps should be frozen when updating the manifest would introduce regressions on ability to install/uninstall the app.
|
||||
Frozen apps should have bugs filed, and fixes for those bugs should unfreeze the app and bump it to the latest version
|
||||
as part of the fix PR.
|
||||
|
||||
## Adding a new app
|
||||
|
||||
1. Decide on a source for the app's metadata. We currently support homebrew as a source for macOS apps.
|
||||
|
||||
@@ -166,6 +166,7 @@ func (i *brewIngester) ingestOne(ctx context.Context, app inputApp) (*maintained
|
||||
|
||||
out.UninstallScriptRef = maintained_apps.GetScriptRef(out.UninstallScript)
|
||||
out.InstallScriptRef = maintained_apps.GetScriptRef(out.InstallScript)
|
||||
out.Frozen = app.Frozen
|
||||
|
||||
return out, nil
|
||||
}
|
||||
@@ -184,6 +185,7 @@ type inputApp struct {
|
||||
PreUninstallScripts []string `json:"pre_uninstall_scripts"`
|
||||
PostUninstallScripts []string `json:"post_uninstall_scripts"`
|
||||
DefaultCategories []string `json:"default_categories"`
|
||||
Frozen bool `json:"frozen"`
|
||||
}
|
||||
|
||||
type brewCask struct {
|
||||
|
||||
@@ -299,6 +299,7 @@ func (i *wingetIngester) ingestOne(ctx context.Context, input inputApp) (*mainta
|
||||
out.UninstallScript = preProcessUninstallScript(uninstallScript, productCode)
|
||||
out.InstallScriptRef = maintained_apps.GetScriptRef(out.InstallScript)
|
||||
out.UninstallScriptRef = maintained_apps.GetScriptRef(out.UninstallScript)
|
||||
out.Frozen = input.Frozen
|
||||
|
||||
return &out, nil
|
||||
}
|
||||
@@ -354,6 +355,7 @@ type inputApp struct {
|
||||
// Whether to use "no_check" instead of the app's hash (e.g. for non-pinned download URLs)
|
||||
IgnoreHash bool `json:"ignore_hash"`
|
||||
DefaultCategories []string `json:"default_categories"`
|
||||
Frozen bool `json:"frozen"`
|
||||
}
|
||||
|
||||
type installerManifest struct {
|
||||
|
||||
@@ -34,6 +34,7 @@ type FMAManifestApp struct {
|
||||
Slug string `json:"-"`
|
||||
Name string `json:"-"`
|
||||
DefaultCategories []string `json:"default_categories"`
|
||||
Frozen bool `json:"-"`
|
||||
}
|
||||
|
||||
func (a *FMAManifestApp) Platform() string {
|
||||
|
||||
Reference in New Issue
Block a user