saltstack / salt

Software to automate the management and configuration of any infrastructure or application at scale. Get access to the Salt software package repository here:
https://repo.saltproject.io/
Apache License 2.0
13.98k stars 5.47k forks source link

[BUG] Unless or Onlyif requisite isn't working anymore in 3007.1 with cmd.run and shell powershell. #66596

Open Gmasquelier opened 1 month ago

Gmasquelier commented 1 month ago

Description

Unless or Onlyif requisite isn't working anymore in 3007.1 with cmd.run and shell powershell.

for example:

test:
  cmd.run:
    - name: echo 'foo'
    - unless: ls /tmp
    - shell: powershell
PS C:\WINDOWS\system32> salt-call state.apply pouet
[INFO    ] Loading fresh modules for state activity
[INFO    ] Fetching file from saltenv 'base', ** done ** 'pouet.sls'
[INFO    ] Running state [echo 'foo'] at time 11:51:50.528154
[INFO    ] Executing state cmd.run for [echo 'foo']
[INFO    ] Executing command C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.EXE in directory 'C:\Users\ta-srv-zidcc-gma'
[ERROR   ] Failed to decode stdout from command C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.EXE, non-decodable characters have been replaced
[INFO    ] ['unless condition is true']
[INFO    ] Completed state [echo 'foo'] at time 11:51:57.768553 (duration_in_ms=7240.399)
[INFO    ] Executing command attrib in directory 'C:\Users\ta-srv-zidcc-gma'
local:
  Name: echo 'foo' - Function: cmd.run - Result: Clean - Started: 11:51:50.528154 - Duration: 7240.399 ms

Summary for local
------------
Succeeded: 1
Failed:    0
------------
Total states run:     1
Total run time:   7.240 s

Here the unless test is alway true whatever the command we use. If we remove the "shell: powershell" the behavior is working as expected.

Setup

salt-minion 3007.1 on windows 10 Virtual Machine

PS C:\WINDOWS\system32> salt-call -V
Salt Version:
          Salt: 3007.1

Python Version:
        Python: 3.10.14 (heads/main:c1ec015, Apr  3 2024, 21:36:37) [MSC v.1938 64 bit (AMD64)]

Dependency Versions:
          cffi: 1.16.0
      cherrypy: 18.8.0
      dateutil: 2.8.2
     docker-py: Not Installed
         gitdb: 4.0.10
     gitpython: Not Installed
        Jinja2: 3.1.4
       libgit2: Not Installed
  looseversion: 1.3.0
      M2Crypto: Not Installed
          Mako: Not Installed
       msgpack: 1.0.7
  msgpack-pure: Not Installed
  mysql-python: Not Installed
     packaging: 23.1
     pycparser: 2.21
      pycrypto: Not Installed
  pycryptodome: 3.19.1
        pygit2: Not Installed
  python-gnupg: 0.5.2
        PyYAML: 6.0.1
         PyZMQ: 25.1.2
        relenv: 0.16.0
         smmap: 5.0.1
       timelib: 0.3.0
       Tornado: 6.3.3
           ZMQ: 4.3.4

Salt Package Information:
  Package Type: onedir

System Versions:
          dist:
        locale: utf-8
       machine: AMD64
       release: 10
        system: Windows
       version: 10 10.0.19045 SP0 Multiprocessor Free

Steps to Reproduce the behavior

It can be reproduce with the command line

salt-call cmd.retcode 'ls /tmp' shell=powershell python_shell=true -l debug --local 
PS C:\WINDOWS\system32>  salt-call cmd.retcode 'ls /tmp' shell=powershell python_shell=true --local -l debug
[DEBUG   ] Reading configuration from C:\salt\conf\minion
[DEBUG   ] Including configuration from 'C:\salt\conf\minion.d\_schedule.conf'
[DEBUG   ] Reading configuration from C:\salt\conf\minion.d\_schedule.conf
[WARNING ] Insecure logging configuration detected! Sensitive data may be logged.
[DEBUG   ] Configuration file path: C:\salt\conf\minion
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from C:\salt\conf\minion
[DEBUG   ] Including configuration from 'C:\salt\conf\minion.d\_schedule.conf'
[DEBUG   ] Reading configuration from C:\salt\conf\minion.d\_schedule.conf
[DEBUG   ] The functions from module 'default_ipv4' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'winrm' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'core' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'disks' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'extra' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'lvm' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'mdadm' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'minion_process' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'opts' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'package' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'pending_reboot' are being loaded by dir() on the loaded module
[DEBUG   ] Override  __utils__: <module 'salt.loaded.int.grains.zfs' from 'C:\\Program Files\\Salt Project\\Salt\\Lib\\site-packages\\salt\\grains\\zfs.py'>
[DEBUG   ] Loading static grains from C:\salt\conf\grains
[DEBUG   ] Determining pillar cache
[DEBUG   ] The functions from module 'roots' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded roots.envs
[DEBUG   ] Popen(['git', 'version'], cwd=C:\WINDOWS\system32, stdin=None, shell=False, universal_newlines=False)
[DEBUG   ] The functions from module 's3fs' are being loaded by dir() on the loaded module
[DEBUG   ] Could not LazyLoad roots.init: 'roots.init' is not available.
[DEBUG   ] Updating roots fileserver cache
[DEBUG   ] The functions from module 'jinja' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] The functions from module 'yaml' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] The functions from module 'jinja' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] The functions from module 'yaml' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] The functions from module 'cmd' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded cmd.retcode
[DEBUG   ] The functions from module 'direct_call' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded direct_call.execute
[DEBUG   ] ['C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.EXE', '-NonInteractive', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', '& {ls /tmp}']
[DEBUG   ] The functions from module 'config' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded config.get
[INFO    ] Executing command C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.EXE in directory 'C:\Users\ta-srv-zidcc-gma'
[ERROR   ] Failed to decode stdout from command C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.EXE, non-decodable characters have been replaced
[DEBUG   ] stdout: ls : Impossible de trouver le chemin d'acc�s ��C:\tmp��, car il n'existe pas.
Au caract�re Ligne:1 : 4
+ & {ls /tmp}
+    ~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\tmp:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
[DEBUG   ] The functions from module 'nested' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded nested.output
local:
    0

The command "ls /tmp" is False but still the module cmd.retcode is sending back 0.

Expected behavior

It used to work in 3007.0.

PS C:\WINDOWS\system32> salt-call -V
Salt Version:
          Salt: 3007.0

Python Version:
        Python: 3.10.13 (heads/main:3079fcb, Feb 19 2024, 03:36:00) [MSC v.1937 64 bit (AMD64)]

Dependency Versions:
          cffi: 1.16.0
      cherrypy: 18.8.0
      dateutil: 2.8.2
     docker-py: Not Installed
         gitdb: Not Installed
     gitpython: Not Installed
        Jinja2: 3.1.3
       libgit2: Not Installed
  looseversion: 1.3.0
      M2Crypto: Not Installed
          Mako: Not Installed
       msgpack: 1.0.7
  msgpack-pure: Not Installed
  mysql-python: Not Installed
     packaging: 23.1
     pycparser: 2.21
      pycrypto: Not Installed
  pycryptodome: 3.19.1
        pygit2: Not Installed
  python-gnupg: 0.5.2
        PyYAML: 6.0.1
         PyZMQ: 25.1.2
        relenv: 0.15.1
         smmap: Not Installed
       timelib: 0.3.0
       Tornado: 6.3.3
           ZMQ: 4.3.4

Salt Package Information:
  Package Type: onedir

System Versions:
          dist:
        locale: utf-8
       machine: AMD64
       release: 10
        system: Windows
       version: 10 10.0.19045 SP0 Multiprocessor Free
PS C:\WINDOWS\system32> salt-call cmd.retcode 'ls /tmp' shell=powershell python_shell=true --local -l debug
[DEBUG   ] Reading configuration from C:\salt\conf\minion
[DEBUG   ] Including configuration from 'C:\salt\conf\minion.d\_schedule.conf'
[DEBUG   ] Reading configuration from C:\salt\conf\minion.d\_schedule.conf
[WARNING ] Insecure logging configuration detected! Sensitive data may be logged.
[DEBUG   ] Configuration file path: C:\salt\conf\minion
[DEBUG   ] Grains refresh requested. Refreshing grains.
[DEBUG   ] Reading configuration from C:\salt\conf\minion
[DEBUG   ] Including configuration from 'C:\salt\conf\minion.d\_schedule.conf'
[DEBUG   ] Reading configuration from C:\salt\conf\minion.d\_schedule.conf
[DEBUG   ] The functions from module 'default_ipv4' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'winrm' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'core' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'disks' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'extra' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'lvm' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'mdadm' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'minion_process' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'opts' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'package' are being loaded by dir() on the loaded module
[DEBUG   ] The functions from module 'pending_reboot' are being loaded by dir() on the loaded module
[DEBUG   ] Override  __utils__: <module 'salt.loaded.int.grains.zfs' from 'C:\\Program Files\\Salt Project\\Salt\\Lib\\site-packages\\salt\\grains\\zfs.py'>
[DEBUG   ] Loading static grains from C:\salt\conf\grains
[DEBUG   ] Determining pillar cache
[DEBUG   ] The functions from module 'roots' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded roots.envs
[DEBUG   ] The functions from module 's3fs' are being loaded by dir() on the loaded module
[DEBUG   ] Could not LazyLoad roots.init: 'roots.init' is not available.
[DEBUG   ] Updating roots fileserver cache
[DEBUG   ] The functions from module 'jinja' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] The functions from module 'yaml' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] The functions from module 'jinja' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded jinja.render
[DEBUG   ] The functions from module 'yaml' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded yaml.render
[DEBUG   ] The functions from module 'cmd' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded cmd.retcode
[DEBUG   ] The functions from module 'direct_call' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded direct_call.execute
[DEBUG   ] The functions from module 'config' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded config.get
[INFO    ] Executing command '"powershell"' in directory 'C:\Users\sa-2a64-3dx-i'
[ERROR   ] Command '"powershell"' failed with return code: 1
[ERROR   ] stdout: ls : Impossible de trouver le chemin d'accès « C:\tmp », car il n'existe pas.
Au caractère Ligne:1 : 1
+ ls /tmp
+ ~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\tmp:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
[ERROR   ] retcode: 1
[DEBUG   ] The functions from module 'nested' are being loaded by dir() on the loaded module
[DEBUG   ] LazyLoaded nested.output
local:
    1
welcome[bot] commented 1 month ago

Hi there! Welcome to the Salt Community! Thank you for making your first contribution. We have a lengthy process for issues and PRs. Someone from the Core Team will follow up as soon as possible. In the meantime, here’s some information that may help as you continue your Salt journey. Please be sure to review our Code of Conduct. Also, check out some of our community resources including:

There are lots of ways to get involved in our community. Every month, there are around a dozen opportunities to meet with other contributors and the Salt Core team and collaborate in real time. The best way to keep track is by subscribing to the Salt Community Events Calendar. If you have additional questions, email us at saltproject@vmware.com. We’re glad you’ve joined our community and look forward to doing awesome things with you!

Gmasquelier commented 1 month ago

it seems related to this recent change:

https://github.com/saltstack/salt/pull/66447/files#diff-700b7d75700c9eafa3ee48d01236e59f37b2ed81d998267136fbcc0224766497L282

PS C:\WINDOWS\system32>  & {ls /tmp}
ls : Impossible de trouver le chemin d'accès « C:\tmp », car il n'existe pas.
Au caractère Ligne:1 : 5
+  & {ls /tmp}
+     ~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\tmp:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

PS C:\WINDOWS\system32> echo $?
True

PS C:\WINDOWS\system32> ls /tmp
ls : Impossible de trouver le chemin d'accès « C:\tmp », car il n'existe pas.
Au caractère Ligne:1 : 1
+ ls /tmp
+ ~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\tmp:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

PS C:\WINDOWS\system32> echo $?
False
PS C:\WINDOWS\system32>

Best regards,

twangboy commented 1 month ago

Could you try changing line 293 from this:

        new_cmd.extend(["-Command", f"& {{{cmd.strip()}}}"])

to this

        new_cmd.extend(["-Command", f'& "{cmd.strip()}"'])
Gmasquelier commented 1 month ago

Yes I confirm that this modification correct the issue.

Best regards,