saltstack / saltstack/salt

[BUG] Using multiple sources in file.blockreplace cause an exception

Open
#62,110 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug needs-triage
Dominant language
Python
Stars
15.7k
Forks
5.6k
Avg merge
2d 44m
Merged PRs (30d)
80

Description

Description
Using multiple sources in file.blockreplace result in an error.

Setup
Salt mastr and salt minion are installed on physical machines

Steps to Reproduce the behavior

Create a state file like this:

test_blockreplace:
    file.blockreplace:
        - name: /tmp/test.txt
        - source: 
            - salt://tmp/test1.txt
            - salt://tmp/test2.txt
        - marker_start: START
        - marker_end: END

And when applied this error is reported:

$ sudo salt foo.bar.loc state.apply test
foo.bar.loc:
----------                                     
          ID: test_blockreplace                                                                                                                                                                                
    Function: file.blockreplace
        Name: /tmp/test.txt                                                                                                                                                                                    
      Result: False
        Name: /tmp/test.txt
      Result: False
     Comment: An exception occurred in this state: Traceback (most recent call last):
                File "/usr/lib/python3/dist-packages/salt/state.py", line 2179, in call
                  ret = self.states[cdata["full"]](
                File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 149, in __call__
                  return self.loader.run(run_func, *args, **kwargs)
                File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 1201, in run
                  return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
                File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 1216, in _run_as
                  return _func_or_method(*args, **kwargs)
                File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 1249, in wrapper
                  return f(*args, **kwargs)
                File "/usr/lib/python3/dist-packages/salt/states/file.py", line 5730, in blockreplace
                  tmpret = _get_template_texts(
                File "/usr/lib/python3/dist-packages/salt/states/file.py", line 1132, in _get_template_texts
                  rndrd_templ_fn = __salt__["cp.get_template"](
                File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 149, in __call__
                  return self.loader.run(run_func, *args, **kwargs)
                File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 1201, in run
                  return self._last_context.run(self._run_as, _func_or_method, *args, **kwargs)
                File "/usr/lib/python3/dist-packages/salt/loader/lazy.py", line 1216, in _run_as
                  return _func_or_method(*args, **kwargs)
                File "/usr/lib/python3/dist-packages/salt/modules/cp.py", line 317, in get_template
                  return _client().get_template(path, dest, template, makedirs, saltenv, **kwargs)
                File "/usr/lib/python3/dist-packages/salt/fileclient.py", line 803, in get_template
                  url_data = urllib.parse.urlparse(url)
                File "/usr/lib/python3.8/urllib/parse.py", line 375, in urlparse
                  url, scheme, _coerce_result = _coerce_args(url, scheme)
                File "/usr/lib/python3.8/urllib/parse.py", line 127, in _coerce_args
                  return _decode_args(args) + (_encode_result,)
                File "/usr/lib/python3.8/urllib/parse.py", line 111, in _decode_args
                  return tuple(x.decode(encoding, errors) if x else '' for x in args)
                File "/usr/lib/python3.8/urllib/parse.py", line 111, in <genexpr>
                  return tuple(x.decode(encoding, errors) if x else '' for x in args)
              AttributeError: 'list' object has no attribute 'decode'
     Started: 17:07:37.830011
    Duration: 247.72 ms
     Changes:   

Summary for foo.bar.loc
------------
Succeeded: 0
Failed:    1

Expected behavior

file.blockreplace shuld process the source list and apply the first file it found like it is stated on: https://docs.saltproject.io/en/latest/ref/states/all/salt.states.file.html

Versions Report

$ salt --versions-report
Salt Version:
          Salt: 3004.1
 
Dependency Versions:
          cffi: Not Installed
      cherrypy: Not Installed
      dateutil: 2.7.3
     docker-py: Not Installed
         gitdb: 2.0.6
     gitpython: 3.0.7
        Jinja2: 2.11.2
       libgit2: Not Installed
      M2Crypto: Not Installed
          Mako: Not Installed
       msgpack: 0.6.2
  msgpack-pure: Not Installed
  mysql-python: Not Installed
     pycparser: Not Installed
      pycrypto: Not Installed
  pycryptodome: 3.6.1
        pygit2: Not Installed
        Python: 3.8.10 (default, Mar 15 2022, 12:22:08)
  python-gnupg: 0.4.5
        PyYAML: 5.3.1
         PyZMQ: 18.1.1
         smmap: 2.0.5
       timelib: Not Installed
       Tornado: 4.5.3
           ZMQ: 4.3.2
 
System Versions:
          dist: ubuntu 20.04 focal
        locale: utf-8
       machine: x86_64
       release: 5.4.0-113-generic
        system: Linux
       version: Ubuntu 20.04 focal

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in salt/states/file.py at blockreplace and _get_template_texts, then follow the cp.get_template path into salt/modules/cp.py and salt/fileclient.py. Reproduce the reported state with two source entries and verify that blockreplace handles the source list without the AttributeError, selecting the first available file as documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devops, infrastructure
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.