From d383876a3c8beaf88a353d4eafa63f342cc628cd Mon Sep 17 00:00:00 2001 From: Roberto Dip Date: Wed, 15 May 2024 19:39:42 -0300 Subject: [PATCH] fix issues installing software in windows (#19048) for #19039 and #19041 this: - fixes the install/remove scripts to read the env variable the proper way - truncates output before storing in the databse in case its longer than MySQL's TEXT size # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Added/updated tests - [x] Manual QA for all new/changed functionality --- pkg/file/scripts/install_exe.ps1 | 2 +- pkg/file/scripts/install_msi.ps1 | 2 +- pkg/file/scripts/remove_exe.ps1 | 2 +- pkg/file/scripts/remove_msi.ps1 | 2 +- .../testdata/scripts/install_exe.ps1.golden | 2 +- .../testdata/scripts/install_msi.ps1.golden | 2 +- .../testdata/scripts/remove_exe.ps1.golden | 2 +- .../testdata/scripts/remove_msi.ps1.golden | 2 +- server/datastore/mysql/scripts.go | 26 +++++++++++-------- server/datastore/mysql/software.go | 15 ++++++++--- 10 files changed, 35 insertions(+), 22 deletions(-) diff --git a/pkg/file/scripts/install_exe.ps1 b/pkg/file/scripts/install_exe.ps1 index e205c4ed11..f9d762b318 100644 --- a/pkg/file/scripts/install_exe.ps1 +++ b/pkg/file/scripts/install_exe.ps1 @@ -1,4 +1,4 @@ -$exeFilePath = "$INSTALLER_PATH" +$exeFilePath = "${env:INSTALLER_PATH}" # extract the name of the executable to use as the sub-directory name $exeName = [System.IO.Path]::GetFileName($exeFilePath) diff --git a/pkg/file/scripts/install_msi.ps1 b/pkg/file/scripts/install_msi.ps1 index 0f7595481d..838c431c1d 100644 --- a/pkg/file/scripts/install_msi.ps1 +++ b/pkg/file/scripts/install_msi.ps1 @@ -1,7 +1,7 @@ $logFile = "${env:TEMP}/fleet-install-software.log" $installProcess = Start-Process msiexec.exe ` - -ArgumentList "/quiet /norestart /lv ${logFile} /i `"$INSTALLER_PATH`"" ` + -ArgumentList "/quiet /norestart /lv ${logFile} /i `"${env:INSTALLER_PATH}`"" ` -PassThru -Verb RunAs -Wait Get-Content $logFile -Tail 500 diff --git a/pkg/file/scripts/remove_exe.ps1 b/pkg/file/scripts/remove_exe.ps1 index eae826c960..abb41892c0 100644 --- a/pkg/file/scripts/remove_exe.ps1 +++ b/pkg/file/scripts/remove_exe.ps1 @@ -1,4 +1,4 @@ -$exeFilePath = "$INSTALLER_PATH" +$exeFilePath = "${env:INSTALLER_PATH}" # extract the name of the executable to use as the sub-directory name $exeName = [System.IO.Path]::GetFileName($exeFilePath) diff --git a/pkg/file/scripts/remove_msi.ps1 b/pkg/file/scripts/remove_msi.ps1 index 23172920ac..dc659508dc 100644 --- a/pkg/file/scripts/remove_msi.ps1 +++ b/pkg/file/scripts/remove_msi.ps1 @@ -1,7 +1,7 @@ $logFile = "${env:TEMP}/fleet-remove-software.log" $removeProcess = Start-Process msiexec.exe ` - -ArgumentList "/quiet /norestart /lv ${logFile} /x `"$INSTALLER_PATH`"" ` + -ArgumentList "/quiet /norestart /lv ${logFile} /x `"${env:INSTALLER_PATH}`"" ` -PassThru -Verb RunAs -Wait Get-Content $logFile -Tail 500 diff --git a/pkg/file/testdata/scripts/install_exe.ps1.golden b/pkg/file/testdata/scripts/install_exe.ps1.golden index e205c4ed11..f9d762b318 100644 --- a/pkg/file/testdata/scripts/install_exe.ps1.golden +++ b/pkg/file/testdata/scripts/install_exe.ps1.golden @@ -1,4 +1,4 @@ -$exeFilePath = "$INSTALLER_PATH" +$exeFilePath = "${env:INSTALLER_PATH}" # extract the name of the executable to use as the sub-directory name $exeName = [System.IO.Path]::GetFileName($exeFilePath) diff --git a/pkg/file/testdata/scripts/install_msi.ps1.golden b/pkg/file/testdata/scripts/install_msi.ps1.golden index 0f7595481d..838c431c1d 100644 --- a/pkg/file/testdata/scripts/install_msi.ps1.golden +++ b/pkg/file/testdata/scripts/install_msi.ps1.golden @@ -1,7 +1,7 @@ $logFile = "${env:TEMP}/fleet-install-software.log" $installProcess = Start-Process msiexec.exe ` - -ArgumentList "/quiet /norestart /lv ${logFile} /i `"$INSTALLER_PATH`"" ` + -ArgumentList "/quiet /norestart /lv ${logFile} /i `"${env:INSTALLER_PATH}`"" ` -PassThru -Verb RunAs -Wait Get-Content $logFile -Tail 500 diff --git a/pkg/file/testdata/scripts/remove_exe.ps1.golden b/pkg/file/testdata/scripts/remove_exe.ps1.golden index eae826c960..abb41892c0 100644 --- a/pkg/file/testdata/scripts/remove_exe.ps1.golden +++ b/pkg/file/testdata/scripts/remove_exe.ps1.golden @@ -1,4 +1,4 @@ -$exeFilePath = "$INSTALLER_PATH" +$exeFilePath = "${env:INSTALLER_PATH}" # extract the name of the executable to use as the sub-directory name $exeName = [System.IO.Path]::GetFileName($exeFilePath) diff --git a/pkg/file/testdata/scripts/remove_msi.ps1.golden b/pkg/file/testdata/scripts/remove_msi.ps1.golden index 23172920ac..dc659508dc 100644 --- a/pkg/file/testdata/scripts/remove_msi.ps1.golden +++ b/pkg/file/testdata/scripts/remove_msi.ps1.golden @@ -1,7 +1,7 @@ $logFile = "${env:TEMP}/fleet-remove-software.log" $removeProcess = Start-Process msiexec.exe ` - -ArgumentList "/quiet /norestart /lv ${logFile} /x `"$INSTALLER_PATH`"" ` + -ArgumentList "/quiet /norestart /lv ${logFile} /x `"${env:INSTALLER_PATH}`"" ` -PassThru -Verb RunAs -Wait Get-Content $logFile -Tail 500 diff --git a/server/datastore/mysql/scripts.go b/server/datastore/mysql/scripts.go index 97305ff1c8..4ecf682f15 100644 --- a/server/datastore/mysql/scripts.go +++ b/server/datastore/mysql/scripts.go @@ -66,6 +66,20 @@ func newHostScriptExecutionRequest(ctx context.Context, request *fleet.HostScrip return &script, nil } +func truncateScriptResult(output string) string { + const maxOutputRuneLen = 10000 + if len(output) > utf8.UTFMax*maxOutputRuneLen { + // truncate the bytes as we know the output is too long, no point + // converting more bytes than needed to runes. + output = output[len(output)-(utf8.UTFMax*maxOutputRuneLen):] + } + if utf8.RuneCountInString(output) > maxOutputRuneLen { + outputRunes := []rune(output) + output = string(outputRunes[len(outputRunes)-maxOutputRuneLen:]) + } + return output +} + func (ds *Datastore) SetHostScriptExecutionResult(ctx context.Context, result *fleet.HostScriptResultPayload) (*fleet.HostScriptResult, error) { const resultExistsStmt = ` SELECT @@ -101,17 +115,7 @@ func (ds *Datastore) SetHostScriptExecutionResult(ctx context.Context, result *f host_id = ? ` - const maxOutputRuneLen = 10000 - output := result.Output - if len(output) > utf8.UTFMax*maxOutputRuneLen { - // truncate the bytes as we know the output is too long, no point - // converting more bytes than needed to runes. - output = output[len(output)-(utf8.UTFMax*maxOutputRuneLen):] - } - if utf8.RuneCountInString(output) > maxOutputRuneLen { - outputRunes := []rune(output) - output = string(outputRunes[len(outputRunes)-maxOutputRuneLen:]) - } + output := truncateScriptResult(result.Output) var hsr *fleet.HostScriptResult err := ds.withRetryTxx(ctx, func(tx sqlx.ExtContext) error { diff --git a/server/datastore/mysql/software.go b/server/datastore/mysql/software.go index 95168e4a9e..4fed1a2b91 100644 --- a/server/datastore/mysql/software.go +++ b/server/datastore/mysql/software.go @@ -14,6 +14,7 @@ import ( _ "github.com/doug-martin/goqu/v9/dialect/mysql" "github.com/fleetdm/fleet/v4/server/contexts/ctxerr" "github.com/fleetdm/fleet/v4/server/fleet" + "github.com/fleetdm/fleet/v4/server/ptr" "github.com/go-kit/kit/log/level" "github.com/jmoiron/sqlx" ) @@ -2049,12 +2050,20 @@ func (ds *Datastore) SetHostSoftwareInstallResult(ctx context.Context, result *f execution_id = ? AND host_id = ? ` + + truncateOutput := func(output *string) *string { + if output != nil { + output = ptr.String(truncateScriptResult(*output)) + } + return output + } + res, err := ds.writer(ctx).ExecContext(ctx, stmt, - result.PreInstallConditionOutput, + truncateOutput(result.PreInstallConditionOutput), result.InstallScriptExitCode, - result.InstallScriptOutput, + truncateOutput(result.InstallScriptOutput), result.PostInstallScriptExitCode, - result.PostInstallScriptOutput, + truncateOutput(result.PostInstallScriptOutput), result.InstallUUID, result.HostID, )