apt_repository: Do not convert symlink repo to a normal file (#82271)

* apt_repository: Do not convert symlink repo to a normal file

* module manually writes to repo files. If the file is a symlink
  module used to re-write and convert a symlink to a normal file.
  This fix tracks the symlink and keeps the changes intact.

Fixes: #49809

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
pull/82316/head
Abhijeet Kasurde 6 months ago committed by GitHub
parent e6e19e37f7
commit 265f5e724c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,3 @@
---
bugfixes:
- apt_repository - do not modify repo files if the file is a symlink (https://github.com/ansible/ansible/issues/49809).

@ -230,6 +230,7 @@ class SourcesList(object):
def __init__(self, module):
self.module = module
self.files = {} # group sources by file
self.files_mapping = {} # internal DS for tracking symlinks
# Repositories that we're adding -- used to implement mode param
self.new_repos = set()
self.default_file = self._apt_cfg_file('Dir::Etc::sourcelist')
@ -240,6 +241,8 @@ class SourcesList(object):
# read sources.list.d
for file in glob.iglob('%s/*.list' % self._apt_cfg_dir('Dir::Etc::sourceparts')):
if os.path.islink(file):
self.files_mapping[file] = os.readlink(file)
self.load(file)
def __iter__(self):
@ -372,7 +375,11 @@ class SourcesList(object):
f.write(line)
except IOError as ex:
self.module.fail_json(msg="Failed to write to file %s: %s" % (tmp_path, to_native(ex)))
self.module.atomic_move(tmp_path, filename)
if filename in self.files_mapping:
# Write to symlink target instead of replacing symlink as a normal file
self.module.atomic_move(tmp_path, self.files_mapping[filename])
else:
self.module.atomic_move(tmp_path, filename)
# allow the user to override the default mode
if filename in self.new_repos:
@ -417,7 +424,7 @@ class SourcesList(object):
def _add_valid_source(self, source_new, comment_new, file):
# We'll try to reuse disabled source if we have it.
# If we have more than one entry, we will enable them all - no advanced logic, remember.
self.module.log('ading source file: %s | %s | %s' % (source_new, comment_new, file))
self.module.log('adding source file: %s | %s | %s' % (source_new, comment_new, file))
found = False
for filename, n, enabled, source, comment in self:
if source == source_new:

@ -253,6 +253,46 @@
- result is failed
- result.msg == 'Please set argument \'repo\' to a non-empty value'
#
# TEST: keep symlink
#
- import_tasks: 'cleanup.yml'
- name: install local-apt-repository with apt
apt: pkg=local-apt-repository state=present
- name: Check if local apt repo file is a symlink
stat:
path: /etc/apt/sources.list.d/local-apt-repository.list
register: stat_result
- name: Assert if local apt repo file is a symlink
assert:
that:
- stat_result.stat.islnk is defined and stat_result.stat.islnk
- stat_result.stat.lnk_source == "/usr/lib/local-apt-repository/local-apt-repository.list"
- name: Try installing an invalid repo
apt_repository:
repo: deb http://dl.google.com/linux/chrome/deb2/ stable main
state: present
filename: google-chrome
ignore_errors: true
- name: Check the stat for the given symlink
stat:
path: /etc/apt/sources.list.d/local-apt-repository.list
register: stat_result2
- name: Assert that the symlink is intact after apt_repository operation
assert:
that:
- stat_result2.stat.islnk is defined and stat_result2.stat.islnk
- stat_result2.stat.lnk_source == "/usr/lib/local-apt-repository/local-apt-repository.list"
- name: uninstall local-apt-repository with apt
apt: pkg=local-apt-repository state=absent purge=yes
#
# TEARDOWN
#

Loading…
Cancel
Save