[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)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.