Support advanced options for script-only packages (#48315)
**Related issue:** Resolves #42797 Adds support for pre-install query, post-install script, and uninstall script on script-only packages (`.sh` and `.ps1`) across the API, UI, and GitOps; previously these were silently stripped. The install script remains the uploaded file's contents (file-driven) and is shown read-only. Automatic install stays unsupported for script-only packages. - **API** (`POST`/`PATCH /software/package`): stop stripping the fields; validate post-install and uninstall scripts for script packages - **GitOps**: allow `uninstall_script`/`post_install_script`/`pre_install_query` paths inline in the team YAML for script-only packages - **UI**: show advanced options for `.sh`/`.ps1`; install script shown read-only # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements), JS inline code is prevented especially for url redirects, and untrusted data interpolated into shell scripts/commands is validated against shell metacharacters. ## Testing - [x] Added/updated automated tests - [x] QA'd all new/changed functionality manually <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Script-only packages (`.sh`/`.ps1`) now expose advanced options—pre-install query, post-install script, and uninstall script—consistently across the UI, REST API, and GitOps. * Script-only packages display advanced options in the UI, and the “Install script” editor can be made read-only where appropriate. * **Bug Fixes** * Preserved advanced option values for script-only packages during upload, edits, and synchronization (including replace-file scenarios). * Improved YAML generation and validation so supported fields are included while unsupported ones are correctly rejected/omitted. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
+18
-5
@@ -283,8 +283,17 @@ type SoftwarePackage struct {
|
||||
}
|
||||
|
||||
func (spec SoftwarePackage) HydrateToPackageLevel(packageLevel fleet.SoftwarePackageSpec, ext string) (fleet.SoftwarePackageSpec, error) {
|
||||
if spec.InstallScript.Path != "" || spec.UninstallScript.Path != "" ||
|
||||
spec.PostInstallScript.Path != "" || spec.URL != "" || spec.SHA256 != "" || spec.PreInstallQuery.Path != "" {
|
||||
isScript := ext == ".sh" || ext == ".ps1"
|
||||
|
||||
// Script-only packages are configured inline in the team YAML, so their
|
||||
// uninstall/post-install scripts and pre-install query are allowed here;
|
||||
// other packages keep those in a package YAML. install_script, url, and hash
|
||||
// are never valid at the team level.
|
||||
if spec.InstallScript.Path != "" || spec.URL != "" || spec.SHA256 != "" ||
|
||||
(!isScript && (spec.UninstallScript.Path != "" || spec.PostInstallScript.Path != "" || spec.PreInstallQuery.Path != "")) {
|
||||
if isScript {
|
||||
return packageLevel, fmt.Errorf("the software package defined in %s must not have install_script, URL, or hash specified at the team level", *spec.Path)
|
||||
}
|
||||
return packageLevel, fmt.Errorf("the software package defined in %s must not have icons, scripts, queries, URL, or hash specified at the team level", *spec.Path)
|
||||
}
|
||||
|
||||
@@ -2188,13 +2197,17 @@ func parseSoftware(top map[string]json.RawMessage, result *GitOps, baseDir strin
|
||||
multiError = multierror.Append(multiError, err)
|
||||
continue
|
||||
}
|
||||
// Script file becomes the install script for a script-only package
|
||||
// The script file is the install script; the uninstall/post-install
|
||||
// scripts and pre-install query come from the team YAML.
|
||||
scriptSpec := fleet.SoftwarePackageSpec{
|
||||
ReferencedYamlPath: resolvedPath,
|
||||
Icon: teamLevelPackage.Icon,
|
||||
UninstallScript: teamLevelPackage.UninstallScript,
|
||||
PostInstallScript: teamLevelPackage.PostInstallScript,
|
||||
PreInstallQuery: teamLevelPackage.PreInstallQuery,
|
||||
}
|
||||
// Icon path needs to be resolved, but since this function will set
|
||||
// the install script it needs to be set to the correct path again.
|
||||
// Resolve icon and script/query paths first; the install script path
|
||||
// is set afterward since it's the script file itself.
|
||||
scriptSpec = scriptSpec.ResolveSoftwarePackagePaths(baseDir)
|
||||
scriptSpec.InstallScript.Path = resolvedPath
|
||||
|
||||
|
||||
Reference in New Issue
Block a user