What is the benefit of /etc/apt/sources.list.d over /etc/apt/sources.list

Having each repository (or collection of repositories) in its own file makes it simpler to manage, both by hand and programmatically:

  • It allows new installations that need their own repos to not have to search a flat file to ensure that it is not adding duplicate entries.
  • It allows a system administrator to easily disable (by renaming) or remove (by deleting) a repository set without having to edit a monolithic file.
  • It allows a package maintainer to give a simple command to update repository locations without having to worry about inadvertently changing the configuration for unrelated repositories.

On a technical level, as someone who has had to handle these changes in a few large and popular system info tools, basically it comes down to this:

For sources.list.d/

# to add
if [[ ! -e /etc/apt/sources.list.d/some_repo.list ]];then
  echo 'some repo line for apt' > /etc/apt/sources.list.d/some_repo.list
fi

# to delete
if [[ -e /etc/apt/sources.list.d/some_repo.list ]];then
  rm -f /etc/apt/sources.list.d/some_repo.list
fi

Note that unless they are also doing the same check as below, if you had commented out a repo line, these tests would be wrong. If they are doing the same check as below, then it's the same exact complexity, except carried out over many files, not one. Also, unless they are checking ALL possible files, they can, and often do, add a duplicate item, which then makes apt complain, until you delete one of them.

For sources.list

# to add. Respect commented out lines. Bonus points for uncommenting
# line instead of adding a new line
if [[ -z $( grep -E '\s*[^#]\s*some repo line for apt' /etc/apt/sources.list ) ]];then
  echo 'some repo line for apt' >> /etc/apt/sources.list
fi

# to delete. Delete whether commented out or not. Bonus for not
# deleting if commented out, thus respecting the user's wishes
sed -i '/.*some repo line for apt.*/d' /etc/apt/sources.list

The Google Chrome devs didn't check for the presence of Google Chrome sources, relying on the exact file name their Chrome package would create to be present. In all other cases, they would create a new file in sources.list.d named exactly the way they wanted.

To see what sources you have, of course, it's not so pretty, since you can't get easier to read and maintain than:

cat /etc/sources.list

So this was basically done for the purpose of automated updates, and to provide easy single commands you could give to users, as far as I can tell. For users, it means that they have to read many files instead of 1 file to see if they have a repo added, and for apt, it means it has to read many files instead of one file as well.

Since in the real world, if you were going to do this well, you have to support checks against all the files, regardless of what they are named, and then test if the action to be carried out is required or not required.

However, if you were not going to do it well, you'd just ignore the checks to see if the item is somewhere in sources, and just check for the file name. I believe that's what most automated stuff does, but since in the end, I simply had to check everything so I could list it and act based on if one of those files matched, the only real result was making it a lot more complicated.

Bulk Edits

Given running many servers, I'd be tempted to just script a nightly job that loops through /etc/apt/sources.list.d/ and checks first to make sure the item is not in sources.list already, then if it is not, add that item to sources.list, delete the sources.list.d file, and if already in sources.list, just delete the sources.list.d file

Since there is NO negative to using only sources.list beyond simplicity and ease of maintenance, adding something like that might not be a bad idea, particularly given creative random actions by sys admins.

As noted in the above comment, inxi -r will neatly print out per file the active repos, but will not of course edit or alter them, so that would be only half the solution. If it's many distributions, it's a pain learning how each does it, that's for sure, and randomness certainly is the rule rather than the exception sadly.


If you're manually managing your servers I'll agree it makes things more confusing. However, it benefits programmatic management (i.e. "configuration as code"). When using config management software like Puppet, Ansible, Chef, etc., it's easier to just drop or remove a file in a dir and run apt update, instead of parsing a file to add or remove certain lines.

Especially since that avoids having to manage the contents of a single 'file' resource, e.g: /etc/apt/sources.list, from multiple independent modules that have been written by third parties.

I appreciate Ubuntu's broad use of ".d" dirs for this particular reason, i.e. sudoers.d, rsyslog.d, sysctl.d., cron.d, logrotate.d, etc.

Tags:

Linux

Apt

Etc