@@ -221,6 +221,7 @@ def __init__(
221221 api_key : str ,
222222 ssh_user : str ,
223223 sign_gpg : bool ,
224+ ssh_key : str | None = None ,
224225 first_state : Task | None = None ,
225226 ) -> None :
226227 self .tasks = tasks
@@ -243,6 +244,8 @@ def __init__(
243244 self .db ["auth_info" ] = api_key
244245 if not self .db .get ("ssh_user" ):
245246 self .db ["ssh_user" ] = ssh_user
247+ if not self .db .get ("ssh_key" ):
248+ self .db ["ssh_key" ] = ssh_key
246249 if not self .db .get ("sign_gpg" ):
247250 self .db ["sign_gpg" ] = sign_gpg
248251
@@ -255,6 +258,7 @@ def __init__(
255258 print (f"- Normalized release tag: { release_tag .normalized ()} " )
256259 print (f"- Git repo: { self .db ['git_repo' ]} " )
257260 print (f"- SSH username: { self .db ['ssh_user' ]} " )
261+ print (f"- SSH key: { self .db ['ssh_key' ] or 'Default' } " )
258262 print (f"- Sign with GPG: { self .db ['sign_gpg' ]} " )
259263 print ()
260264
@@ -340,17 +344,23 @@ def check_ssh_connection(db: ReleaseShelf) -> None:
340344 client = paramiko .SSHClient ()
341345 client .load_system_host_keys ()
342346 client .set_missing_host_key_policy (paramiko .WarningPolicy )
343- client .connect (DOWNLOADS_SERVER , port = 22 , username = db ["ssh_user" ])
347+ client .connect (
348+ DOWNLOADS_SERVER , port = 22 , username = db ["ssh_user" ], key_filename = db ["ssh_key" ]
349+ )
344350 client .exec_command ("pwd" )
345- client .connect (DOCS_SERVER , port = 22 , username = db ["ssh_user" ])
351+ client .connect (
352+ DOCS_SERVER , port = 22 , username = db ["ssh_user" ], key_filename = db ["ssh_key" ]
353+ )
346354 client .exec_command ("pwd" )
347355
348356
349357def check_sigstore_client (db : ReleaseShelf ) -> None :
350358 client = paramiko .SSHClient ()
351359 client .load_system_host_keys ()
352360 client .set_missing_host_key_policy (paramiko .WarningPolicy )
353- client .connect (DOWNLOADS_SERVER , port = 22 , username = db ["ssh_user" ])
361+ client .connect (
362+ DOWNLOADS_SERVER , port = 22 , username = db ["ssh_user" ], key_filename = db ["ssh_key" ]
363+ )
354364 _ , stdout , _ = client .exec_command ("python3 -m sigstore --version" )
355365 sigstore_version = stdout .read (1000 ).decode ()
356366 sigstore_vermatch = re .match ("^sigstore ([0-9.]+)" , sigstore_version )
@@ -659,7 +669,7 @@ def sign_source_artifacts(db: ReleaseShelf) -> None:
659669
660670 subprocess .check_call (
661671 [
662- "python3" ,
672+ sys . executable ,
663673 "-m" ,
664674 "sigstore" ,
665675 "sign" ,
@@ -730,7 +740,7 @@ def upload_files_to_server(db: ReleaseShelf, server: str) -> None:
730740 client = paramiko .SSHClient ()
731741 client .load_system_host_keys ()
732742 client .set_missing_host_key_policy (paramiko .WarningPolicy )
733- client .connect (server , port = 22 , username = db ["ssh_user" ])
743+ client .connect (server , port = 22 , username = db ["ssh_user" ], key_filename = db [ "ssh_key" ] )
734744 transport = client .get_transport ()
735745 assert transport is not None , f"SSH transport to { server } is None"
736746
@@ -775,7 +785,9 @@ def place_files_in_download_folder(db: ReleaseShelf) -> None:
775785 client = paramiko .SSHClient ()
776786 client .load_system_host_keys ()
777787 client .set_missing_host_key_policy (paramiko .WarningPolicy )
778- client .connect (DOWNLOADS_SERVER , port = 22 , username = db ["ssh_user" ])
788+ client .connect (
789+ DOWNLOADS_SERVER , port = 22 , username = db ["ssh_user" ], key_filename = db ["ssh_key" ]
790+ )
779791 transport = client .get_transport ()
780792 assert transport is not None , f"SSH transport to { DOWNLOADS_SERVER } is None"
781793
@@ -826,7 +838,9 @@ def unpack_docs_in_the_docs_server(db: ReleaseShelf) -> None:
826838 client = paramiko .SSHClient ()
827839 client .load_system_host_keys ()
828840 client .set_missing_host_key_policy (paramiko .WarningPolicy )
829- client .connect (DOCS_SERVER , port = 22 , username = db ["ssh_user" ])
841+ client .connect (
842+ DOCS_SERVER , port = 22 , username = db ["ssh_user" ], key_filename = db ["ssh_key" ]
843+ )
830844 transport = client .get_transport ()
831845 assert transport is not None , f"SSH transport to { DOCS_SERVER } is None"
832846
@@ -968,7 +982,9 @@ def wait_until_all_files_are_in_folder(db: ReleaseShelf) -> None:
968982 client = paramiko .SSHClient ()
969983 client .load_system_host_keys ()
970984 client .set_missing_host_key_policy (paramiko .WarningPolicy )
971- client .connect (DOWNLOADS_SERVER , port = 22 , username = db ["ssh_user" ])
985+ client .connect (
986+ DOWNLOADS_SERVER , port = 22 , username = db ["ssh_user" ], key_filename = db ["ssh_key" ]
987+ )
972988 ftp_client = client .open_sftp ()
973989
974990 destination = f"/srv/www.python.org/ftp/python/{ db ['release' ].normalized ()} "
@@ -1006,7 +1022,9 @@ def run_add_to_python_dot_org(db: ReleaseShelf) -> None:
10061022 client = paramiko .SSHClient ()
10071023 client .load_system_host_keys ()
10081024 client .set_missing_host_key_policy (paramiko .WarningPolicy )
1009- client .connect (DOWNLOADS_SERVER , port = 22 , username = db ["ssh_user" ])
1025+ client .connect (
1026+ DOWNLOADS_SERVER , port = 22 , username = db ["ssh_user" ], key_filename = db ["ssh_key" ]
1027+ )
10101028 transport = client .get_transport ()
10111029 assert transport is not None , f"SSH transport to { DOWNLOADS_SERVER } is None"
10121030
@@ -1344,6 +1362,13 @@ def _api_key(api_key: str) -> str:
13441362 help = "Username to be used when authenticating via ssh" ,
13451363 type = str ,
13461364 )
1365+ parser .add_argument (
1366+ "--ssh-key" ,
1367+ dest = "ssh_key" ,
1368+ default = None ,
1369+ help = "Path to the SSH key file to use for authentication" ,
1370+ type = str ,
1371+ )
13471372 args = parser .parse_args ()
13481373
13491374 auth_key = args .auth_key or os .getenv ("AUTH_INFO" )
@@ -1432,6 +1457,7 @@ def _api_key(api_key: str) -> str:
14321457 api_key = auth_key ,
14331458 ssh_user = args .ssh_user ,
14341459 sign_gpg = not no_gpg ,
1460+ ssh_key = args .ssh_key ,
14351461 tasks = tasks ,
14361462 )
14371463 automata .run ()
0 commit comments