1818import subprocess
1919import asyncio
2020import logging
21- import gnupg
21+ from jinja2 import Template
2222from typing import Awaitable , Callable , List , Tuple
2323from charon .storage import S3Client
24- from getpass import getpass
2524
2625logger = logging .getLogger (__name__ )
2726
@@ -33,34 +32,22 @@ def generate_sign(
3332 prefix : str ,
3433 s3_client : S3Client ,
3534 bucket : str ,
36- key_id : str = None ,
37- key_file : str = None ,
38- sign_method : str = None ,
39- passphrase : str = None
35+ key : str = None ,
36+ command : str = None
4037) -> Tuple [List [str ], List [str ]]:
4138 """ This Python function generates a digital signature for a list of metadata files using
4239 the GPG library for uploads to an Amazon S3 bucket.
4340
4441 * Does not regenerate the existing metadata files when existing
4542 * Returning all failed to generate signature files due to exceptions
46- * key_id: A string representing the ID of the RSA key to use for signing,
47- GPG command line tool is required when this parameter is not None.
48- * key_file: A string representing the location of the private key file.
49- * passphrase: A string containing the passphrase for the RSA key for key_id or key_file.
43+ * key: name of the sign key, using inside template to render correct command,
44+ replace {{ key }} field in command string.
45+ * command: A string representing the subprocess command to run.
5046
5147 It returns a tuple containing two lists: one with the successfully generated files
5248 and another with the failed to generate files due to exceptions.
5349 """
5450
55- gpg = None
56- if key_file is not None :
57- gnupg_home_path = os .path .join (os .getenv ("HOME" ), ".charon" , ".gnupg" )
58- gpg = gnupg .GPG (gnupghome = gnupg_home_path )
59- gpg .import_keys_file (key_file )
60-
61- if sign_method == 'gpg' and passphrase is None :
62- passphrase = getpass ('Passphrase for your gpg key:' )
63-
6451 async def sign_file (
6552 filename : str , failed_paths : List [str ], generated_signs : List [str ]
6653 ):
@@ -93,18 +80,12 @@ async def sign_file(
9380 logger .debug (".asc file %s existed, skipping" , remote )
9481 return
9582
96- if sign_method == "rpm-sign" :
97- result = detach_rpm_sign_files (key_id , artifact )
98- elif sign_method == "gpg" :
99- result = gpg_sign_files (
100- gpg = gpg ,
101- artifact = artifact ,
102- key_id = key_id , key_file = key_file ,
103- passphrase = passphrase
104- )
83+ run_command = Template (command )
84+ result = await __run_cmd_async (run_command .render (key = key , file = artifact ).split ())
10585
106- if result == 0 :
86+ if result . returncode == 0 :
10787 generated_signs .append (local )
88+ logger .debug ("Generated signature file: %s" , local )
10889 else :
10990 failed_paths .append (local )
11091
@@ -115,82 +96,6 @@ async def sign_file(
11596 )
11697
11798
118- def detach_rpm_sign_files (key : str , artifact : str ) -> int :
119- # Usage: detach_sign_files KEYNAME FILE ...
120-
121- # let's make sure we can actually sign with the given key
122- command = [
123- 'rpm-sign' ,
124- '--list-keys' ,
125- '|' ,
126- 'grep' ,
127- key
128- ]
129- result = subprocess .run (command , capture_output = True , text = True , check = True )
130- if result .returncode != 0 :
131- logger .error ("Key %s is not in list of allowed keys" , key )
132- return result .returncode
133-
134- # okay, now let's actually sign this thing
135- command = [
136- 'rpm-sign' ,
137- '--detachsign' ,
138- '--key' ,
139- key ,
140- artifact
141- ]
142- try :
143- # result = await __run_cmd_async(command)
144- result = subprocess .run (command , capture_output = True , text = True , check = True )
145- except subprocess .CalledProcessError as e :
146- logger .error (
147- "Error: signature generation failed due to error: %s" , e
148- )
149- return result .returncode
150-
151- return 1
152-
153-
154- def gpg_sign_files (
155- artifact : str ,
156- gpg = None ,
157- key_id : str = None ,
158- key_file : str = None ,
159- passphrase : str = None
160- ) -> int :
161- command = [
162- 'gpg' ,
163- '--batch' ,
164- '--armor' ,
165- '-u' , key_id ,
166- '--passphrase' , passphrase ,
167- '--sign' , artifact
168- ]
169-
170- if key_file is None :
171- # use GPG command line tool to sign artifact if key_id is passed
172- try :
173- # result = await __run_cmd_async(command)
174- result = subprocess .run (command , capture_output = True , text = True , check = True )
175- except subprocess .CalledProcessError as e :
176- logger .error (
177- "Error: signature generation failed due to error: %s" , e
178- )
179- return result .returncode
180- else :
181- try :
182- with open (artifact , "rb" ) as f :
183- local = artifact + '.asc'
184- gpg .sign_file (f , passphrase = passphrase , output = local , detach = True )
185- return 0
186- except ValueError as e :
187- logger .error (
188- "Error: signature generation failed due to error: %s" , e
189- )
190- return 1
191- return 1
192-
193-
19499def __do_path_cut_and (
195100 file_paths : List [str ],
196101 path_handler : Callable [[str , List [str ], List [str ], asyncio .Semaphore ], Awaitable [bool ]],
0 commit comments