-
-
Notifications
You must be signed in to change notification settings - Fork 37
Add new ssh key argument and don't check magic number in old versions #234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -193,6 +193,8 @@ | |
api_key: str, | ||
ssh_user: str, | ||
sign_gpg: bool, | ||
ssh_key: str | None = None, | ||
security_release: bool = False, | ||
first_state: Task | None = None, | ||
) -> None: | ||
self.tasks = tasks | ||
|
@@ -215,8 +217,12 @@ | |
self.db["auth_info"] = api_key | ||
if not self.db.get("ssh_user"): | ||
self.db["ssh_user"] = ssh_user | ||
if not self.db.get("ssh_key"): | ||
self.db["ssh_key"] = ssh_key | ||
if not self.db.get("sign_gpg"): | ||
self.db["sign_gpg"] = sign_gpg | ||
if not self.db.get("security_release"): | ||
self.db["security_release"] = security_release | ||
|
||
if not self.db.get("release"): | ||
self.db["release"] = release_tag | ||
|
@@ -227,8 +233,10 @@ | |
print(f"- Normalized release tag: {release_tag.normalized()}") | ||
print(f"- Git repo: {self.db['git_repo']}") | ||
print(f"- SSH username: {self.db['ssh_user']}") | ||
print(f"- SSH key: {self.db['ssh_key'] or 'Default'}") | ||
print(f"- python.org API key: {self.db['auth_info']}") | ||
print(f"- Sign with GPG: {self.db['sign_gpg']}") | ||
print(f"- Security release: {self.db['security_release']}") | ||
print() | ||
|
||
def checkpoint(self) -> None: | ||
|
@@ -313,17 +321,23 @@ | |
client = paramiko.SSHClient() | ||
client.load_system_host_keys() | ||
client.set_missing_host_key_policy(paramiko.WarningPolicy) | ||
client.connect(DOWNLOADS_SERVER, port=22, username=db["ssh_user"]) | ||
client.connect( | ||
DOWNLOADS_SERVER, port=22, username=db["ssh_user"], key_filename=db["ssh_key"] | ||
) | ||
client.exec_command("pwd") | ||
client.connect(DOCS_SERVER, port=22, username=db["ssh_user"]) | ||
client.connect( | ||
DOCS_SERVER, port=22, username=db["ssh_user"], key_filename=db["ssh_key"] | ||
) | ||
client.exec_command("pwd") | ||
|
||
|
||
def check_sigstore_client(db: ReleaseShelf) -> None: | ||
client = paramiko.SSHClient() | ||
client.load_system_host_keys() | ||
client.set_missing_host_key_policy(paramiko.WarningPolicy) | ||
client.connect(DOWNLOADS_SERVER, port=22, username=db["ssh_user"]) | ||
client.connect( | ||
DOWNLOADS_SERVER, port=22, username=db["ssh_user"], key_filename=db["ssh_key"] | ||
) | ||
_, stdout, _ = client.exec_command("python3 -m sigstore --version") | ||
sigstore_version = stdout.read(1000).decode() | ||
sigstore_vermatch = re.match("^sigstore ([0-9.]+)", sigstore_version) | ||
|
@@ -398,6 +412,9 @@ | |
|
||
def check_magic_number(db: ReleaseShelf) -> None: | ||
release_tag = db["release"] | ||
if release_tag.major == 3 and release_tag.minor <= 13: | ||
return | ||
|
||
if release_tag.is_final or release_tag.is_release_candidate: | ||
|
||
def out(msg: str) -> None: | ||
|
@@ -623,7 +640,7 @@ | |
|
||
subprocess.check_call( | ||
[ | ||
"python3", | ||
sys.executable, | ||
"-m", | ||
"sigstore", | ||
"sign", | ||
|
@@ -692,7 +709,7 @@ | |
client = paramiko.SSHClient() | ||
client.load_system_host_keys() | ||
client.set_missing_host_key_policy(paramiko.WarningPolicy) | ||
client.connect(server, port=22, username=db["ssh_user"]) | ||
client.connect(server, port=22, username=db["ssh_user"], key_filename=db["ssh_key"]) | ||
transport = client.get_transport() | ||
assert transport is not None, f"SSH transport to {server} is None" | ||
|
||
|
@@ -737,7 +754,9 @@ | |
client = paramiko.SSHClient() | ||
client.load_system_host_keys() | ||
client.set_missing_host_key_policy(paramiko.WarningPolicy) | ||
client.connect(DOWNLOADS_SERVER, port=22, username=db["ssh_user"]) | ||
client.connect( | ||
DOWNLOADS_SERVER, port=22, username=db["ssh_user"], key_filename=db["ssh_key"] | ||
) | ||
transport = client.get_transport() | ||
assert transport is not None, f"SSH transport to {DOWNLOADS_SERVER} is None" | ||
|
||
|
@@ -788,7 +807,9 @@ | |
client = paramiko.SSHClient() | ||
client.load_system_host_keys() | ||
client.set_missing_host_key_policy(paramiko.WarningPolicy) | ||
client.connect(DOCS_SERVER, port=22, username=db["ssh_user"]) | ||
client.connect( | ||
DOCS_SERVER, port=22, username=db["ssh_user"], key_filename=db["ssh_key"] | ||
) | ||
transport = client.get_transport() | ||
assert transport is not None, f"SSH transport to {DOCS_SERVER} is None" | ||
|
||
|
@@ -905,7 +926,9 @@ | |
client = paramiko.SSHClient() | ||
client.load_system_host_keys() | ||
client.set_missing_host_key_policy(paramiko.WarningPolicy) | ||
client.connect(DOWNLOADS_SERVER, port=22, username=db["ssh_user"]) | ||
client.connect( | ||
DOWNLOADS_SERVER, port=22, username=db["ssh_user"], key_filename=db["ssh_key"] | ||
) | ||
ftp_client = client.open_sftp() | ||
|
||
destination = f"/srv/www.python.org/ftp/python/{db['release'].normalized()}" | ||
|
@@ -923,18 +946,34 @@ | |
are_windows_files_there = f"python-{release}.exe" in all_files | ||
are_macos_files_there = f"python-{release}-macos11.pkg" in all_files | ||
are_linux_files_there = f"Python-{release}.tgz" in all_files | ||
are_all_files_there = ( | ||
are_linux_files_there and are_windows_files_there and are_macos_files_there | ||
) | ||
|
||
if db["security_release"]: | ||
# For security releases, only check Linux files | ||
are_all_files_there = are_linux_files_there | ||
else: | ||
# For regular releases, check all platforms | ||
are_all_files_there = ( | ||
are_linux_files_there | ||
and are_windows_files_there | ||
and are_macos_files_there | ||
) | ||
|
||
if not are_all_files_there: | ||
linux_tick = "✅" if are_linux_files_there else "❌" | ||
windows_tick = "✅" if are_windows_files_there else "❌" | ||
macos_tick = "✅" if are_macos_files_there else "❌" | ||
print( | ||
f"\rWaiting for files: Linux {linux_tick} Windows {windows_tick} Mac {macos_tick} ", | ||
flush=True, | ||
end="", | ||
) | ||
if db["security_release"]: | ||
print( | ||
f"\rWaiting for files: Linux {linux_tick} (security release mode - only checking Linux) ", | ||
flush=True, | ||
end="", | ||
) | ||
else: | ||
print( | ||
f"\rWaiting for files: Linux {linux_tick} Windows {windows_tick} Mac {macos_tick} ", | ||
flush=True, | ||
end="", | ||
) | ||
time.sleep(1) | ||
print() | ||
|
||
|
@@ -943,7 +982,9 @@ | |
client = paramiko.SSHClient() | ||
client.load_system_host_keys() | ||
client.set_missing_host_key_policy(paramiko.WarningPolicy) | ||
client.connect(DOWNLOADS_SERVER, port=22, username=db["ssh_user"]) | ||
client.connect( | ||
DOWNLOADS_SERVER, port=22, username=db["ssh_user"], key_filename=db["ssh_key"] | ||
) | ||
transport = client.get_transport() | ||
assert transport is not None, f"SSH transport to {DOWNLOADS_SERVER} is None" | ||
|
||
|
@@ -1259,6 +1300,20 @@ | |
help="Username to be used when authenticating via ssh", | ||
type=str, | ||
) | ||
parser.add_argument( | ||
"--ssh-key", | ||
dest="ssh_key", | ||
default=None, | ||
help="Path to the SSH key file to use for authentication", | ||
type=str, | ||
) | ||
parser.add_argument( | ||
"--security-release", | ||
dest="security_release", | ||
action="store_true", | ||
default=False, | ||
help="Indicate this is a security release (only checks for Linux files)", | ||
) | ||
Comment on lines
+1310
to
+1316
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And similarly, we could check the status in the JSON file. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here's a PR to check the status from the devguide, so the RM doesn't have to remember to pass Merging that will update this PR. |
||
args = parser.parse_args() | ||
|
||
auth_key = args.auth_key or os.getenv("AUTH_INFO") | ||
|
@@ -1353,6 +1408,8 @@ | |
api_key=auth_key, | ||
ssh_user=args.ssh_user, | ||
sign_gpg=not no_gpg, | ||
ssh_key=args.ssh_key, | ||
security_release=args.security_release, | ||
tasks=tasks, | ||
) | ||
automata.run() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to avoid hardcoding this, as it's another thing that needs adding to a longish list when a new version comes around.
Perhaps we can fetch the newest version from https://github.com/python/devguide/blob/main/include/release-cycle.json (and later from python/peps#4331)?
This can also be a followup PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the first version that needed this feature. How fetching the newer version would be cleaner ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it always only the current feature release that this check will apply for? If so, perhaps expanding the
security
Boolean to a branch status enum would be better, as then we could test if branch-status == feature here.A
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this particular check applies to all releases that are after we changed that file, that is, anything above or including 3.13
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, if the limit is always 3.13 and we don't need to change it, then a hardcoded version makes sense here.
Let's use a tuple so we don't need to worry about Python 4 :)