lowlydba / lowlydba.sqlserver

:spoon: A cross-platform Ansible collection using PowerShell to configure and maintain SQL Server.
https://galaxy.ansible.com/ui/repo/published/lowlydba/sqlserver
GNU General Public License v3.0
19 stars 12 forks source link

pwsh experimental/fixes #175

Closed briantist closed 1 year ago

briantist commented 1 year ago

Description

How Has This Been Tested?

CI

Types of changes

Checklist:

codecov-commenter commented 1 year ago

Codecov Report

Base: 93.78% // Head: 93.78% // No change to project coverage :thumbsup:

Coverage data is based on head (f48e84c) compared to base (3051f0a). Patch has no changes to coverable lines.

Additional details and impacted files ```diff @@ Coverage Diff @@ ## main #175 +/- ## ======================================= Coverage 93.78% 93.78% ======================================= Files 64 64 Lines 2188 2188 ======================================= Hits 2052 2052 Misses 136 136 ``` Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=John+McCall). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=John+McCall)

:umbrella: View full report at Codecov.
:loudspeaker: Do you have feedback about the report comment? Let us know in this issue.

briantist commented 1 year ago

After getting through the initial failures (related to the compilation problems) by updating the experimental plugins, we have two new issues.

On 2.12 only:

Exception calling "Create" with "3" argument(s): "EventLog access is not supported on this platform."

This doesn't make sense... it implies that the Ansible.Basic module being used is the one included with ansible (which doesn't have the changes from 2.13 that make it work), but the changes I made to the experimental plugins should ensure that 2.12 uses the vendored modified module utils in the role. I confirmed locally that this works, the conditional for the ansible version is working and using the local copies. I don't have an answer yet for why this is (seemingly) failing in CI.

2.13 and 2.14 work as expected; it's worth noting that the compilation issue only comes up in PowerShell 7.3, and the test container for those doesn't include it, so this mainly shows that the modifications to the experimental plugins are working correctly on these versions (using the module utils included in those core versions).

devel now has a different problem that also stems from PowerShell 7.3.

The 'Get-DbaDbUser' command was found in the module 'dbatools', but the module could not be loaded. For more information, run 'Import-Module dbatools'.
At line:45 char:17
+ $existingUser = Get-DbaDbUser @getUserSplat
+                 ~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Get-DbaDbUser:String) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : CouldNotAutoloadMatchingModule

Every invocation of a dbatools command gives an auto-load error like this.

This might to be related to this change (maybe):

I can't actually confirm that though, it might be unrelated.

I thought I'd check to see if doing an explicit Import-Module instead of just using #Requires might help it: https://github.com/lowlydba/lowlydba.sqlserver/pull/175/commits/97a1904e8b23092aab834bc5fa7123af9ecce82f

In CI we can see that this failed spectacularly: https://github.com/lowlydba/lowlydba.sqlserver/actions/runs/4225543845/jobs/7337956510#step:9:197

Basically it just acted as though the module doesn't exist, but it should have been installed in the previous step. Side note, do you remember why no_log was set here? https://github.com/lowlydba/lowlydba.sqlserver/blob/main/tests/integration/targets/setup_sqlserver/tasks/main.yml#L6

When I tried this import thing locally, it failed in a different but also incredibly confusing way:

Full traceback ``` The full traceback is: Exception calling "Invoke" with "3" argument(s): "The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: Could not import /home/briantist/.local/share/powershell/Modules/dbatools/1.1.112/bin/smo/coreclr/Microsoft.SqlServer.XEvent.Linq.dll : MethodInvocationException: /home/briantist/.local/share/powershell/Modules/dbatools/1.1.112/internal/scripts/libraryimport.ps1:150 Line | 150 | [Reflection.Assembly]::LoadFrom($assemblyPath) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Exception calling "LoadFrom" with "1" argument(s): "Could not load file or assembly '/home/briantist/.local/share/powershell/Modules/dbatools/1.1.112/bin/smo/coreclr/Microsoft.SqlServer.XEvent.Linq.dll'. An attempt was made to load a program with an incorrect format. " " At /home/briantist/.local/share/powershell/Modules/dbatools/1.1.112/internal/scripts/libraryimport.ps1:161 char:50 + … Invoke($script:PSModuleRoot, "$(Join-Path $script:DllRoot smo)", $scr … + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : ActionPreferenceStopException ScriptStackTrace: at , /home/briantist/.local/share/powershell/Modules/dbatools/1.1.112/internal/scripts/libraryimport.ps1: line 161 at , /home/briantist/.local/share/powershell/Modules/dbatools/1.1.112/dbatools.psm1: line 214 at , : line 10 fatal: [localhost]: FAILED! => { "changed": false, "msg": "Unhandled exception while executing module: Exception calling \"Invoke\" with \"3\" argument(s): \"The running command stopped because the preference variable \"ErrorActionPreference\" or common parameter is set to Stop: Could not import /home/briantist/.local/share/powershell/Modules/dbatools/1.1.112/bin/smo/coreclr/Microsoft.SqlServer.XEvent.Linq.dll : \nMethodInvocationException: /home/briantist/.local/share/powershell/Modules/dbatools/1.1.112/internal/scripts/libraryimport.ps1:150\nLine |\n 150 | [Reflection.Assembly]::LoadFrom($assemblyPath)\n | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n | Exception calling \"LoadFrom\" with \"1\" argument(s): \"Could not load file or assembly '/home/briantist/.local/share/powershell/Modules/dbatools/1.1.112/bin/smo/coreclr/Microsoft.SqlServer.XEvent.Linq.dll'. An attempt was made to load a program with an incorrect format. \"\n\n\"" } ```

So that's the current state... :(

briantist commented 1 year ago

Ok so I've solved some of the above mysteries:


Error with explicit import in the ansible module:

The full traceback is:
Exception calling "Invoke" with "3" argument(s): "The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: Could not import /root/.local/share/powershell/Modules/dbatools/1.1.145/bin/smo/coreclr/Microsoft.SqlServer.XE.Core.dll :
MethodInvocationException: /root/.local/share/powershell/Modules/dbatools/1.1.145/internal/scripts/libraryimport.ps1:150
Line |
 150 |                      [Reflection.Assembly]::LoadFrom($assemblyPath)
     |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | Exception calling "LoadFrom" with "1" argument(s): "Could not load file or assembly '/root/.local/share/powershell/Modules/dbatools/1.1.145/bin/smo/coreclr/Microsoft.SqlServer.XE.Core.dll'. An attempt was made to load a program with an incorrect format. "

"
At /root/.local/share/powershell/Modules/dbatools/1.1.145/internal/scripts/libraryimport.ps1:161 char:50
+ … Invoke($script:PSModuleRoot, "$(Join-Path $script:DllRoot smo)", $scr …
+                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : ActionPreferenceStopException

ScriptStackTrace:
at <ScriptBlock>, /root/.local/share/powershell/Modules/dbatools/1.1.145/internal/scripts/libraryimport.ps1: line 161
at <ScriptBlock>, /root/.local/share/powershell/Modules/dbatools/1.1.145/dbatools.psm1: line 226
at <ScriptBlock>, <No file>: line 10
fatal: [testhost]: FAILED! => {
    "changed": false,
    "msg": "Unhandled exception while executing module: Exception calling \"Invoke\" with \"3\" argument(s): \"The running command stopped because the preference variable \"ErrorActionPreference\" or common parameter is set to Stop: Could not import /root/.local/share/powershell/Modules/dbatools/1.1.145/bin/smo/coreclr/Microsoft.SqlServer.XE.Core.dll : \nMethodInvocationException: /root/.local/share/powershell/Modules/dbatools/1.1.145/internal/scripts/libraryimport.ps1:150\nLine |\n 150 |                      [Reflection.Assembly]::LoadFrom($assemblyPath)\n     |                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n     | Exception calling \"LoadFrom\" with \"1\" argument(s): \"Could not load file or assembly '/root/.local/share/powershell/Modules/dbatools/1.1.145/bin/smo/coreclr/Microsoft.SqlServer.XE.Core.dll'. An attempt was made to load a program with an incorrect format. \"\n\n\""
}

MCVE:

ansible localhost -m command -a 'pwsh -c "ipmo dbatools -verbose"'

the above seems to happen no matter which version of ansible, so I wonder if it's solely related to the version of pwsh

briantist commented 1 year ago

thanks @jborean93 for help troubleshooting

It seems that there are assemblies in dbatools that don't load because they are for the wrong platform, and that this has been the case for a while. For some reason, PowerShell versions before 7.3 hid these(?), and for whatever reason these errors are now showing up in some error stream. They seem to still be ignored by PowerShell sort of, you don't normally see them, but things like Ansible look at the error stream and see them.


repros for showing the dbatools error:

Ansible

ansible localhost -m command -a 'pwsh -c "ipmo dbatools -verbose"'

PowerShell

$ErrorActionPreference = "Stop"
Import-Module dbatools

NOTE: ipmo dbatools -ea Stop does not produce the error

$ps = [PowerShell]::Create()
$ps.AddScript('Import-Module dbatools').Invoke()
$ps.Streams.Error
lowlydba commented 1 year ago

Thanks so much for all this work and investigation 🙇🏻 !


Side note, do you remember why no_log was set here? https://github.com/lowlydba/lowlydba.sqlserver/blob/main/tests/integration/targets/setup_sqlserver/tasks/main.yml#L6

I think I had tried a few methods to make the install less verbose since it was writing way too many lines out in noninteractive mode, but had trouble and just used no_log as a workaround.

When I tried this import thing locally, it failed in a different but also incredibly confusing way: .... So that's the current state... :(

That behavior looks to be captured by https://github.com/dataplat/dbatools/issues/8657. As wsmelton mentions there, apparently pwsh 7.3 included the move to .NET 7 so that probably explains the abrupt change in behavior. I'm going to look into it from that angle a bit, but have low expectations.

lowlydba commented 1 year ago

The preview of 2.0 works!

Quick repro:

Install-Module dbatools -AllowPrerelease -Force
ansible localhost -m command -a 'pwsh -c "ipmo dbatools -verbose"'

I don't get the impression that < 2.0 will get any of the needed fixes backported, it probably makes sense to do an enhancement that checks for 2.0+ when the pwsh version is >= 7.3 in the CI. It might also be worth it to set the new min version to 2.0 once it is finally released to avoid any confusing compatibility issues as well.

briantist commented 1 year ago

imo, let's merge this, and use #177 and a new PR to deal with 2.0 if <2 is never fixed, wdyt?

lowlydba commented 1 year ago

imo, let's merge this, and use #177 and a new PR to deal with 2.0 if <2 is never fixed, wdyt?

You read my mind.