Skip to content

Conversation

aemous
Copy link
Contributor

@aemous aemous commented Oct 9, 2025

Description of changes:

  • Implemented runtime checks for the following breaking changes via --v2-debug:
    • Usage of PYTHONUTF8 and PYTHONIOENCODING env vars unsupported in v2.
    • S3 copies executed under aws s3 namespace may call additional APIs for multipart S3 copies
    • Signer used for S3 request is Sigv2 (I expect it's very rare for customers to be using sigv2 and run into this)
    • [!] aws cloudformation deploy will not fail on empty changesets.
    • Timestamps in responses will be formatted in ISO 8601.
    • Usage of file:// with blob-type parameters.
    • us-east-1 will use the regional endpoint in v2 rather than global.
    • Usage of api_versions in config will not be supported in v2.
    • Support for [plugins] will be provisional in v2.
    • Pagination params used in --cli-input-json will disable automatic paging in v2.
  • Line-length formatting of other --v2-debug code.
  • Added tests to cover some added functionality

Description of tests:

  • Ran and passed all new tests.
  • Manually tested the file encoding checker by supplying PYTHONUTF8:
$ PYTHONUTF8=1 python3 -m awscli s3 ls --v2-debug
AWS CLI v2 MIGRATION WARNING: The PYTHONUTF8 and PYTHONIOENCODING environment variables are unsupported in AWS CLI v2. AWS CLI v2 uses AWS_CLI_FILE_ENCODING instead, set this environment variable to resolve this. See https://docs.aws.amazon.com/cli/latest/userguide/cliv2-migration-changes.html#cliv2-migration-encodingenvvar.

An error occurred (ExpiredToken) when calling the ListBuckets operation: The provided token has expired.
  • Manually tested the s3 copies checker via aws s3 cp:
$ python3 -m awscli s3 cp s3://BUCKET1/file1 s3://BUCKET2 --v2-debug
AWS CLI v2 MIGRATION WARNING: In AWS CLI v2, object properties will be copied from the source in multipart copies between S3 buckets. This may result in extra S3 API calls being made. Breakage may occur if the principal does not have permission to call these extra APIs. This warning cannot be resolved. See https://docs.aws.amazon.com/cli/latest/userguide/cliv2-migration-changes.html#cliv2-migration-s3-copy-metadata

copy: s3://BUCKET1/file1 to s3://BUCKET2
  • Manually tested the timestamps checker via aws s3 ls:
AWS CLI v2 MIGRATION WARNING: In AWS CLI v2, all timestamp response values are returned in the ISO 8601 format. To migrate to v2 behavior and resolve this warning, set the configuration variable `cli_timestamp_format` to `iso8601`. See https://docs.aws.amazon.com/cli/latest/userguide/cliv2-migration-changes.html#cliv2-migration-timestamp.
[...]
  • Manually tested specifying pagination params through --cli-input-json:
 $ aws s3api list-buckets --v2-debug --cli-input-json file://pagination-params.json 
AWS CLI v2 MIGRATION WARNING: In AWS CLI v2, if you specify pagination parameters by using a file with the `--cli-input-json` parameter, automatic pagination will be turned off. This is not the case in v1. See https://docs.aws.amazon.com/cli/latest/userguide/cliv2-migration-changes.html#cliv2-migration-skeleton-paging.
[...]
  • Manually tested specifying api_versions in config file:
api_versions =
    ec2 = 2016-11-15
    s3 = 2006-03-01
$ aws s3 ls --v2-debug
AWS CLI v2 MIGRATION WARNING: The AWS CLI v2 does not support calling earlier versions of AWS service APIs via the `api_versions` configuration file setting. To migrate to v2 behavior and resolve this warning, remove the `api_versions` setting in the configuration file. See https://docs.aws.amazon.com/cli/latest/userguide/cliv2-migration-changes.html#cliv2-migration-api-versions.
  • Manually tested using file:// for a blob-type parameter:
$ python3 -m awscli secretsmanager update-secret --secret-id SECRET-NAME --secret-binary file://BINARY-SECRET.json --v2-debug
AWS CLI v2 MIGRATION WARNING: When specifying a blob-type parameter starting with `file://`, AWS CLI v2 will assume the content of the file is already base64-encoded. To maintain v1 behavior after upgrading to v2, set the `cli_binary_format` configuration variable to `raw-in-base64-out`. See https://docs.aws.amazon.com/cli/latest/userguide/cliv2-migration-changes.html#cliv2-migration-binaryparam.
{
    "ARN": "ARN",
    "Name": "SECRET-NAME",
    "VersionId": "VERSION-ID"
}

After setting cli_binary_format to raw-in-base64-out, I've verified that the warning above was not printed.

  • Manually tested configuring region to us-east-1 and executing an S3 command:
$ python3 -m awscli s3 ls --v2-debug 
AWS CLI v2 MIGRATION WARNING: When you configure AWS CLI v2 to use the `us-east-1` region, it uses the true regional endpoint rather than the global endpoint. To continue using the global endpoint on v2, configure the region to be `aws-global`. See https://docs.aws.amazon.com/cli/latest/userguide/cliv2-migration-changes.html#cliv2-migration-s3-regional-endpoint.

After setting region to aws-global, I've verified that the warning above was not printed.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@aemous aemous requested a review from a team October 9, 2025 14:37
@codecov-commenter
Copy link

codecov-commenter commented Oct 9, 2025

Codecov Report

❌ Patch coverage is 83.95062% with 13 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (debug-migration@1fee97f). Learn more about missing BASE report.

Files with missing lines Patch % Lines
awscli/customizations/globalargs.py 78.12% 7 Missing ⚠️
awscli/customizations/scalarparse.py 66.66% 4 Missing ⚠️
awscli/clidriver.py 90.00% 1 Missing ⚠️
awscli/customizations/cloudformation/deploy.py 66.66% 1 Missing ⚠️
Additional details and impacted files
@@                Coverage Diff                 @@
##             debug-migration    #9775   +/-   ##
==================================================
  Coverage                   ?   93.28%           
==================================================
  Files                      ?      209           
  Lines                      ?    16885           
  Branches                   ?        0           
==================================================
  Hits                       ?    15752           
  Misses                     ?     1133           
  Partials                   ?        0           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

return sync_strategies

def run(self):
def run(self, v2_debug=False):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this go through self.parameters instead? That looks like where we're handling other info from parsed_globals.

Comment on lines 71 to 75
encountered_timestamp = False
def identity_with_warning(x):
nonlocal encountered_timestamp
if not encountered_timestamp:
encountered_timestamp = True
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain this flow better in comments? Is it so we're only printing a single warning per response?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, without adding these guards I was getting flooded with messages (one per timestamp in the responses), which nearly made the feature unusable.

I'll update with comments

Comment on lines 278 to 283
# This function checks for pagination args in the actual calling
# arguments passed to the function. If the user is using the
# --cli-input-json parameter to provide JSON parameters they are
# all in the API naming space rather than the CLI naming space
# and would be missed by the processing above. This function gets
# called on the calling-command event.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally prefer docstrings throughout. Though we don't generate user-facing docs from these, they're more helpful in IDEs for us and contributors.

Comment on lines +191 to +193
# The regional us-east-1 endpoint is used in certain cases (e.g.
# FIPS/Dual-Stack is enabled). Rather than duplicating this logic
# from botocore, we check the endpoint URL directly.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this why we need the actual endpoint check in addition to the us_east_1_regional_endpoint + us-east-1 logic above?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

parser = ArgTableArgParser(arg_table)
return parser

def _detect_migration_breakage(self, session, parsed_args, parsed_globals, arg_table):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is only dealing with the file://, then I think it'd be good to add that to the method name. I wouldn't want someone else to add logic that gets skipped by the early return.

_resolve_timeout(session, parsed_args, arg_name)

def detect_migration_breakage(parsed_args, remaining_args, session, **kwargs):
if parsed_args.v2_debug:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given how long this got, it'd be nice to return early here if the mode isn't enabled to save an indent level.

Comment on lines 288 to 290
pagination_params_in_input_tokens = [
param for param in call_parameters if param in input_tokens
]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this limited to --cli-input-json?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point! Did some testing and it actually prints the warning even when its specified on the command directly. I'll need to fix this to maybe check what params came from cli-input-json and access them in paginate.py.

Will address in next revision

@aemous aemous requested a review from ashovlin October 14, 2025 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants