@@ -133,16 +133,19 @@ def create_rpm_pkgs(self, artifacts_path, gpg_key_name):
133133 """
134134
135135 def create_repo_file (self , file_path , binary_name , baseurl , gpgkey_url ):
136- with open (os .path .join (file_path , binary_name + '.repo' ), "w+" ) as repo_file :
136+ repo_file = os .path .join (file_path , binary_name + '.repo' )
137+ with open (repo_file , "w+" ) as repo_file :
137138 repo_file .write (f"[{ binary_name } -stable]" )
138139 repo_file .write (f"{ binary_name } -stable" )
139140 repo_file .write (f"baseurl={ baseurl } /rpm" )
140141 repo_file .write ("enabled=1" )
141142 repo_file .write ("type=rpm" )
142143 repo_file .write ("gpgcheck=1" )
143144 repo_file .write (f"gpgkey={ gpgkey_url } " )
145+ return repo_file
144146
145- def _sign_rpms (self , file_path ):
147+
148+ def _sign_rpms (self , file_path , gpg_key_name ):
146149 p = Popen (["rpm" , "--define" , f"_gpg_name { gpg_key_name } " , "--addsign" , file_path ], stdout = PIPE , stderr = PIPE )
147150 out , err = p .communicate ()
148151 if p .returncode != 0 :
@@ -176,7 +179,7 @@ def _setup_rpm_pkg_directories(self, artifacts_path, gpg_key_name, archs=["aarch
176179 old_path = os .path .join (root , file )
177180 new_path = os .path .join (new_dir , file )
178181 shutil .copyfile (old_path , new_path )
179- self ._sign_rpms (new_path )
182+ self ._sign_rpms (new_path , gpg_key_name )
180183
181184 """
182185 imports gpg keys into the system so reprepro and createrepo can use it to sign packages.
@@ -192,6 +195,18 @@ def import_gpg_keys(self, private_key, public_key):
192195 data = gpg .list_keys (secret = True )
193196 return (data [0 ]["fingerprint" ], data [0 ]["uids" ][0 ])
194197
198+ def import_multiple_gpg_keys (self , primary_private_key , primary_public_key , secondary_private_key = None , secondary_public_key = None ):
199+ """
200+ Import one or two GPG keypairs. Returns a list of (fingerprint, uid) with the primary first.
201+ """
202+ results = []
203+ if primary_private_key and primary_public_key :
204+ results .append (self .import_gpg_keys (primary_private_key , primary_public_key ))
205+ if secondary_private_key and secondary_public_key :
206+ # Ensure secondary is imported and appended
207+ results .append (self .import_gpg_keys (secondary_private_key , secondary_public_key ))
208+ return results
209+
195210 """
196211 basically rpm --import <key_file>
197212 This enables us to sign rpms.
@@ -247,11 +262,13 @@ def upload_from_directories(pkg_uploader, directory, release, binary):
247262"""
248263
249264
250- def create_deb_packaging (pkg_creator , pkg_uploader , releases , gpg_key_id , binary_name , archs , package_component ,
265+ def create_deb_packaging (pkg_creator , pkg_uploader , releases , primary_gpg_key_id , secondary_gpg_key_id , binary_name , archs , package_component ,
251266 release_version ):
252267 # set configuration for package creation.
253268 print (f"initialising configuration for { binary_name } , { archs } " )
254269 Path ("./conf" ).mkdir (parents = True , exist_ok = True )
270+ # If in rollover mode (secondary provided), tell reprepro to sign with both keys.
271+ sign_with_ids = primary_gpg_key_id if not secondary_gpg_key_id else f"{ primary_gpg_key_id } { secondary_gpg_key_id } "
255272 pkg_creator .create_distribution_conf (
256273 "./conf/distributions" ,
257274 binary_name ,
@@ -260,7 +277,7 @@ def create_deb_packaging(pkg_creator, pkg_uploader, releases, gpg_key_id, binary
260277 archs ,
261278 package_component ,
262279 f"apt repository for { binary_name } " ,
263- gpg_key_id )
280+ sign_with_ids )
264281
265282 # create deb pkgs
266283 for release in releases :
@@ -287,15 +304,19 @@ def create_rpm_packaging(
287304 gpg_key_name ,
288305 base_url ,
289306 gpg_key_url ,
307+ upload_repo_file = False ,
290308):
291309 print (f"creating rpm pkgs..." )
292310 pkg_creator .create_rpm_pkgs (artifacts_path , gpg_key_name )
293- pkg_creator .create_repo_file (artifacts_path , binary_name , base_url , gpg_key_url )
311+ repo_file = pkg_creator .create_repo_file (artifacts_path , binary_name , base_url , gpg_key_url )
312+
313+ print ("Uploading repo file" )
314+ pkg_uploader .upload_pkg_to_r2 (repo_file , binary_name + "repo" )
294315
295316 print ("uploading latest to r2..." )
296317 upload_from_directories (pkg_uploader , "rpm" , None , binary_name )
297318
298- if release_version :
319+ if upload_repo_file :
299320 print (f"uploading versioned release { release_version } to r2..." )
300321 upload_from_directories (pkg_uploader , "rpm" , release_version , binary_name )
301322
@@ -336,11 +357,23 @@ def parse_args():
336357 signing packages"
337358 )
338359
360+ # Optional secondary keypair for key rollover
361+ parser .add_argument (
362+ "--gpg-private-key-2" , default = os .environ .get ("LINUX_SIGNING_PRIVATE_KEY_2" ), help = "Secondary GPG private key for rollover"
363+ )
364+ parser .add_argument (
365+ "--gpg-public-key-2" , default = os .environ .get ("LINUX_SIGNING_PUBLIC_KEY_2" ), help = "Secondary GPG public key for rollover"
366+ )
367+
339368 parser .add_argument (
340369 "--gpg-public-key-url" , default = os .environ .get ("GPG_PUBLIC_KEY_URL" ), help = "GPG public key url that\
341370 downloaders can use to verify signing"
342371 )
343372
373+ parser .add_argument (
374+ "--gpg-public-key-url-2" , default = os .environ .get ("GPG_PUBLIC_KEY_URL_2" ), help = "Secondary GPG public key url for rollover"
375+ )
376+
344377 parser .add_argument (
345378 "--pkg-upload-url" , default = os .environ .get ("PKG_URL" ), help = "URL to be used by downloaders"
346379 )
@@ -355,6 +388,10 @@ def parse_args():
355388 it is the caller's responsiblity to ensure that these debs are already present in a directory. This script\
356389 will not build binaries or create their debs."
357390 )
391+
392+ parser .add_argument (
393+ "--upload-repo-file" , action = 'store_true' , help = "Upload RPM repo file to R2"
394+ )
358395 args = parser .parse_args ()
359396
360397 return args
@@ -368,21 +405,45 @@ def parse_args():
368405 exit (1 )
369406
370407 pkg_creator = PkgCreator ()
371- (gpg_key_id , gpg_key_name ) = pkg_creator .import_gpg_keys (args .gpg_private_key , args .gpg_public_key )
408+ # Import one or two keypairs; primary first
409+ key_results = pkg_creator .import_multiple_gpg_keys (
410+ args .gpg_private_key ,
411+ args .gpg_public_key ,
412+ args .gpg_private_key_2 ,
413+ args .gpg_public_key_2 ,
414+ )
415+ if not key_results or len (key_results ) == 0 :
416+ raise SystemExit ("No GPG keys were provided for signing" )
417+ primary_gpg_key_id , primary_gpg_key_name = key_results [0 ]
418+ secondary_gpg_key_id = None
419+ secondary_gpg_key_name = None
420+ if len (key_results ) > 1 :
421+ secondary_gpg_key_id , secondary_gpg_key_name = key_results [1 ]
422+ # Import RPM public keys (one or two)
372423 pkg_creator .import_rpm_key (args .gpg_public_key )
373424
374425 pkg_uploader = PkgUploader (args .account , args .bucket , args .id , args .secret )
375- print (f"signing with gpg_key: { gpg_key_id } " )
376- create_deb_packaging (pkg_creator , pkg_uploader , args .deb_based_releases , gpg_key_id , args .binary , args .archs ,
377- "main" , args .release_tag )
426+ print (f"signing with primary gpg_key: { primary_gpg_key_id } and secondary gpg_key: { secondary_gpg_key_id } " )
427+ create_deb_packaging (
428+ pkg_creator ,
429+ pkg_uploader ,
430+ args .deb_based_releases ,
431+ primary_gpg_key_id ,
432+ secondary_gpg_key_id ,
433+ args .binary ,
434+ args .archs ,
435+ "main" ,
436+ args .release_tag ,
437+ )
378438
379439 create_rpm_packaging (
380440 pkg_creator ,
381441 pkg_uploader ,
382442 "./built_artifacts" ,
383443 args .release_tag ,
384444 args .binary ,
385- gpg_key_name ,
386- args .gpg_public_key_url ,
445+ primary_gpg_key_name ,
387446 args .pkg_upload_url ,
447+ args .gpg_public_key_url ,
448+ args .upload_repo_file ,
388449 )
0 commit comments