11import asyncio
22import json
33import os
4- import pathlib
54import shutil
65import socket
76import ssl
@@ -1072,43 +1071,61 @@ def _dispatch_task_group(task_name, *args, **kwargs):
10721071
10731072# GPG related fixtures
10741073
1074+ PULP_FIXTURES_SIGNING_KEYS_URL = (
1075+ "https://raw.githubusercontent.com/pulp/pulp-fixtures/master/common/signing_keys/"
1076+ )
1077+ KEY_V4_RSA2K_PUBLIC = PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v4-rsa2k.asc"
1078+ KEY_V4_RSA2K_PRIVATE = PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v4-rsa2k.secret"
1079+ KEY_V4_RSA4K_PUBLIC = PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v4-rsa4k.asc"
1080+ KEY_V4_RSA4K_PRIVATE = PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v4-rsa4k.secret"
1081+ KEY_V4_ED25519_PUBLIC = PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v4-ed25519.asc"
1082+ KEY_V4_ED25519_PRIVATE = PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v4-ed25519.secret"
1083+ KEY_V6_RSA4K_PUBLIC = PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v6-rsa4k.asc"
1084+ KEY_V6_RSA4K_PRIVATE = PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v6-rsa4k.secret"
1085+ KEY_V6_ED25519_PUBLIC = PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v6-ed25519.asc"
1086+ KEY_V6_ED25519_PRIVATE = PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v6-ed25519.secret"
1087+ KEY_V6_MLDSA65_ED25519_PUBLIC = (
1088+ PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v6-mldsa65-ed25519.asc"
1089+ )
1090+ KEY_V6_MLDSA65_ED25519_PRIVATE = (
1091+ PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v6-mldsa65-ed25519.secret"
1092+ )
1093+ KEY_V6_MLDSA87_ED448_PUBLIC = PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v6-mldsa87-ed448.asc"
1094+ KEY_V6_MLDSA87_ED448_PRIVATE = (
1095+ PULP_FIXTURES_SIGNING_KEYS_URL + "pulp-testkey-v6-mldsa87-ed448.secret"
1096+ )
1097+
10751098
1076- SIGNING_SCRIPT_STRING = r """#!/usr/bin/env bash
1099+ SIGNING_SCRIPT_STRING = """#!/usr/bin/env bash
10771100
10781101FILE_PATH=$1
10791102SIGNATURE_PATH="$1.asc"
10801103
1081- GPG_KEY_ID="pulp-fixture-signing-key "
1104+ GPG_KEY_ID="{gpg_key_id} "
10821105
10831106# Create a detached signature
1084- gpg --quiet --batch --homedir HOMEDIRHERE --detach-sign --local-user "${GPG_KEY_ID}" \
1085- --armor --output ${SIGNATURE_PATH} ${FILE_PATH}
1107+ gpg --quiet --batch --homedir {gpg_home} --detach-sign --local-user "${{ GPG_KEY_ID}}" \ \
1108+ --armor --output ${{ SIGNATURE_PATH}} ${{ FILE_PATH} }
10861109
10871110# Check the exit status
10881111STATUS=$?
1089- if [[ ${STATUS} -eq 0 ]]; then
1090- echo {\ "file\ ": \"${ FILE_PATH}\ ", \ "signature\ ": \"${ SIGNATURE_PATH}\"}
1112+ if [[ ${{ STATUS} } -eq 0 ]]; then
1113+ echo '{{ "file": "'${{ FILE_PATH}}' ", "signature": "'${{ SIGNATURE_PATH}}'"}}'
10911114else
1092- exit ${STATUS}
1115+ exit ${{ STATUS} }
10931116fi
10941117"""
10951118
10961119
10971120@pytest .fixture (scope = "session" )
1098- def signing_script_path (signing_script_temp_dir , signing_gpg_homedir_path ):
1099- signing_script_file = signing_script_temp_dir / "sign-metadata.sh"
1100- signing_script_file .write_text (
1101- SIGNING_SCRIPT_STRING .replace ("HOMEDIRHERE" , str (signing_gpg_homedir_path ))
1102- )
1103-
1104- signing_script_file .chmod (0o755 )
1105-
1106- return signing_script_file
1121+ def signing_script_path (signing_script_temp_dir , signing_gpg_homedir_path , signing_gpg_metadata ):
1122+ _gpg , fingerprint , _keyid = signing_gpg_metadata
1123+ return make_signing_script (signing_gpg_homedir_path , fingerprint , signing_script_temp_dir )
11071124
11081125
11091126@pytest .fixture (scope = "session" )
11101127def signing_script_temp_dir (tmp_path_factory ):
1111- return tmp_path_factory .mktemp ("sigining_script_dir " )
1128+ return tmp_path_factory .mktemp ("signing_script_dir " )
11121129
11131130
11141131@pytest .fixture (scope = "session" )
@@ -1149,30 +1166,7 @@ def _sign_with_ascii_armored_detached_signing_service(filename):
11491166def signing_gpg_metadata (signing_gpg_homedir_path ):
11501167 """A fixture that returns a GPG instance and related metadata (i.e., fingerprint, keyid)."""
11511168 PRIVATE_KEY_URL = "https://raw.githubusercontent.com/pulp/pulp-fixtures/master/common/GPG-PRIVATE-KEY-fixture-signing" # noqa: E501
1152-
1153- try :
1154- import gnupg
1155- except ImportError :
1156- pytest .fail ("python-gnupg is not installed, add to your functest_requirements.txt" )
1157- key_file = pathlib .Path (__file__ ).parent / "GPG-PRIVATE-KEY-fixture-signing"
1158- if key_file .exists ():
1159- private_key_data = key_file .read_text ()
1160- else :
1161- response = requests .get (PRIVATE_KEY_URL )
1162- response .raise_for_status ()
1163- private_key_data = response .text
1164- with suppress (FileNotFoundError , PermissionError ):
1165- key_file .write_text (private_key_data )
1166-
1167- gpg = gnupg .GPG (gnupghome = signing_gpg_homedir_path )
1168- gpg .import_keys (private_key_data )
1169-
1170- key = gpg .list_keys ()[0 ]
1171- fingerprint = key ["fingerprint" ]
1172- keyid = key ["keyid" ]
1173-
1174- gpg .trust_keys (fingerprint , "TRUST_ULTIMATE" )
1175- return gpg , fingerprint , keyid
1169+ return import_signing_key (PRIVATE_KEY_URL , signing_gpg_homedir_path )
11761170
11771171
11781172@pytest .fixture (scope = "session" )
@@ -1194,53 +1188,102 @@ def _ascii_armored_detached_signing_service_name(
11941188 signing_gpg_metadata ,
11951189 signing_gpg_homedir_path ,
11961190):
1197- service_name = str (uuid .uuid4 ())
11981191 _gpg , fingerprint , _keyid = signing_gpg_metadata
1192+ service_name = create_signing_service (
1193+ signing_gpg_homedir_path , fingerprint , signing_script_path
1194+ )
1195+
1196+ yield service_name
1197+
1198+ remove_signing_service (service_name )
1199+
1200+
1201+ @pytest .fixture (scope = "session" )
1202+ def ascii_armored_detached_signing_service (
1203+ _ascii_armored_detached_signing_service_name , pulpcore_bindings
1204+ ):
1205+ return pulpcore_bindings .SigningServicesApi .list (
1206+ name = _ascii_armored_detached_signing_service_name
1207+ ).results [0 ]
1208+
11991209
1210+ def import_signing_key (key_url , gpg_home ):
1211+ """Import a PGP key into a GPG home directory and trust it.
1212+
1213+ Returns ``(gpg, fingerprint, keyid)``.
1214+ """
1215+ try :
1216+ import gnupg
1217+ except ImportError :
1218+ pytest .skip ("python-gnupg not installed" )
1219+
1220+ gpg = gnupg .GPG (gnupghome = gpg_home )
1221+
1222+ response = requests .get (key_url )
1223+ response .raise_for_status ()
1224+ result = gpg .import_keys (response .content )
1225+ assert result .count >= 1 , f"Failed to import key from { key_url } "
1226+
1227+ key_info = gpg .list_keys ()[0 ]
1228+ fingerprint = key_info ["fingerprint" ]
1229+ keyid = key_info ["keyid" ]
1230+ gpg .trust_keys (fingerprint , "TRUST_ULTIMATE" )
1231+
1232+ return gpg , fingerprint , keyid
1233+
1234+
1235+ def make_signing_script (gpg_home , fingerprint , script_dir = None ):
1236+ """Create a detached-signature signing script.
1237+
1238+ Returns the script path.
1239+ """
1240+ if script_dir is None :
1241+ script_dir = gpg_home
1242+ script_path = script_dir / "sign.sh"
1243+ script_path .write_text (SIGNING_SCRIPT_STRING .format (gpg_home = gpg_home , gpg_key_id = fingerprint ))
1244+ script_path .chmod (0o755 )
1245+ return script_path
1246+
1247+
1248+ def create_signing_service (
1249+ gpg_home , fingerprint , script_path , * , service_class = "core:AsciiArmoredDetachedSigningService"
1250+ ):
1251+ """Register a signing service via pulpcore-manager.
1252+
1253+ Returns the service name.
1254+ """
1255+ service_name = str (uuid .uuid4 ())
12001256 cmd = (
12011257 "pulpcore-manager" ,
12021258 "add-signing-service" ,
12031259 service_name ,
1204- str (signing_script_path ),
1260+ str (script_path ),
12051261 fingerprint ,
12061262 "--class" ,
1207- "core:AsciiArmoredDetachedSigningService" ,
1263+ service_class ,
12081264 "--gnupghome" ,
1209- str (signing_gpg_homedir_path ),
1210- )
1211- completed_process = subprocess .run (
1212- cmd ,
1213- stdout = subprocess .PIPE ,
1214- stderr = subprocess .PIPE ,
1265+ str (gpg_home ),
12151266 )
1267+ completed = subprocess .run (cmd , capture_output = True , text = True )
1268+ assert completed .returncode == 0 , completed .stderr
12161269
1217- assert completed_process . returncode == 0
1270+ return service_name
12181271
1219- yield service_name
12201272
1221- cmd = (
1222- "pulpcore-manager" ,
1223- "remove-signing-service" ,
1224- service_name ,
1225- "--class" ,
1226- "core:AsciiArmoredDetachedSigningService" ,
1227- )
1273+ def remove_signing_service (service_name , service_class = "core:AsciiArmoredDetachedSigningService" ):
1274+ """Remove a signing service created by ``create_signing_service``."""
12281275 subprocess .run (
1229- cmd ,
1230- stdout = subprocess .PIPE ,
1231- stderr = subprocess .PIPE ,
1276+ (
1277+ "pulpcore-manager" ,
1278+ "remove-signing-service" ,
1279+ service_name ,
1280+ "--class" ,
1281+ service_class ,
1282+ ),
1283+ capture_output = True ,
12321284 )
12331285
12341286
1235- @pytest .fixture (scope = "session" )
1236- def ascii_armored_detached_signing_service (
1237- _ascii_armored_detached_signing_service_name , pulpcore_bindings
1238- ):
1239- return pulpcore_bindings .SigningServicesApi .list (
1240- name = _ascii_armored_detached_signing_service_name
1241- ).results [0 ]
1242-
1243-
12441287# if content_origin == None, base_url will return the relative path and
12451288# we need to add the hostname to run the tests
12461289@pytest .fixture (scope = "session" )
0 commit comments