[sysadmin/neon-tooling] lib/apt: apt-key is deprecated and removed in resolute
Carlos De Maine <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 2e592a3d8c986abb7e516caf9553e31d9d7f4936 by Carlos De Maine.
Committed on 19/07/2026 at 01:54.
Pushed by carlosdem into branch 'master'.
apt-key is deprecated and removed in resolute
port to wrap gpg instead
M +46 -22 lib/apt/key.rb
https://invent.kde.org/sysadmin/neon-tooling/-/commit/2e592a3d8c986abb7e516caf9553e31d9d7f4936
diff --git a/lib/apt/key.rb b/lib/apt/key.rb
index 1b50021c..30f05d9d 100644
--- a/lib/apt/key.rb
+++ b/lib/apt/key.rb
@@ -19,23 +19,25 @@
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
require 'open-uri'
+require 'fileutils'
+require 'securerandom'
module Apt
- # Apt key management using apt-key binary
+ # Apt key management replacing deprecated apt-key binary
class Key
+ KEYRING_DIR = '/etc/apt/keyrings'
+
class << self
+ # apt-key has been deprecated so we now wrap gpg to handles basic key management
def method_missing(name, *caller_args)
- system('apt-key', name.to_s.tr('_', '-'), *caller_args)
+ warn "Warning: Calling deprecated apt-key wrapper for command '#{name}'"
+ system('gpg', '--homedir', KEYRINGS_DIR, name.to_s.tr('_', '-'), *caller_args)
end
- # Add a GPG key to APT.
+ # Add a GPG key to APT keyrings directory.
# @param str [String] can be a file path, or an http/https/ftp URI or
- # a fingerprint/keyid or a fucking file, if you pass a fucking file you
- # are an idiot.
+ # a fingerprint/keyid.
def add(str)
- # If the thing passes for an URI with host and path we use it as url
- # otherwise as fingerprint. file:// uris would not qualify, we do not
- # presently have a use case for them though.
if url?(str)
add_url(str)
else
@@ -45,29 +47,51 @@ module Apt
def add_url(url)
data = URI.open(url).read
- IO.popen(['apt-key', 'add', '-'], 'w') do |io|
- io.puts(data)
- io.close_write
- end
- $?.success?
+ # Use a stable identifier for the filename, if it's a file path, use the basename,
+ # otherwise generate a secure unique token.
+ name = url.start_with?('/') ? File.basename(url) : "apt-key-#{SecureRandom.hex(4)}"
+ save_dearmored_key(data, name)
end
def add_fingerprint(id_or_fingerprint)
- system('apt-key', 'adv',
- '--keyserver', 'keyserver.ubuntu.com',
- '--recv', id_or_fingerprint)
+ tmp_key = "/tmp/#{id_or_fingerprint}.key"
+ success = system('gpg', '--no-default-keyring', '--keyring', tmp_key,
+ '--keyserver', 'keyserver.ubuntu.com', '--recv-keys', id_or_fingerprint)
+ return false unless success && File.exist?(tmp_key)
+
+ data = File.read(tmp_key)
+ File.delete(tmp_key)
+
+ save_dearmored_key(data, id_or_fingerprint)
end
private
+ def save_dearmored_key(raw_data, base_name)
+ clean_name = base_name.gsub(/[^a-zA-Z0-9.\-_]/, '_')
+ clean_name += '.gpg' unless clean_name.end_with?('.gpg')
+ target_path = File.join(KEYRING_DIR, clean_name)
+
+ FileUtils.mkdir_p(KEYRING_DIR)
+
+ IO.popen(['gpg', '--dearmor', '-o', target_path], 'w') do |io|
+ io.write(raw_data)
+ end
+ $?.success?
+ end
+
def fingerprint_added?(str)
- output = `apt-key adv --fingerprint '#{str}'`
- return false if output.nil? || !$?.success? # May be nil from mocking!
+ return false unless Dir.exist?(KEYRINGS_DIR)
+ Dir.glob(File.join(KEYRINGS_DIR, '*.gpg')).each do |keyring|
+ output = `gpg --show-keys --with-fingerprint "#{keyring}" 2>/dev/null`
+ next if output.nil? || !$?.success?
- # This is a bit imprecise, but cheapest way to do it without having
- # to parse the output as a whole. By only querying --fingerprint this
- # should still be reasonably accurate.
- output.include?(str)
+ # This is a bit imprecise, but cheapest way to do it without having
+ # to parse the output as a whole. By only querying --fingerprint this
+ # should still be reasonably accurate.
+ output.include?(str)
+ end
+ false
end
def url?(str)