Problem Statement
The gdk component publish command does not check for the existence of a component's artifact version in the S3 bucket before uploading. This behavior results in the command overwriting the S3 object (or creating a new version if versioning is enabled). While the S3 upload itself might succeed, the subsequent CreateComponentVersion call fails, and any deployments using the component version result in an ARTIFACT_CHECKSUM_MISMATCH error.
This happens because the gdk-cli first uploads the artifact to S3 and then attempts to create the Greengrass component version using the CreateComponentVersion API. If a component with the same name and version already exists in the AWS account, the API call will fail, but the S3 artifact has already been overwritten, corrupting the link between the S3 object and the Greengrass component.
To Reproduce
Run gdk component publish for a component with a specific version (e.g., 1.0.0).
Run gdk component publish again for the exact same component and version.
Observe the following error in the terminal:
botocore.errorfactory.ConflictException: An error occurred (ConflictException) when calling the CreateComponentVersion operation: Component [component_name : version] for account [AWS_ACCOUNT_ID] already exists with state: [DEPLOYABLE]
If a Greengrass deployment is attempted with this component version, it will fail with an ARTIFACT_CHECKSUM_MISMATCH error.
Expected Behavior
The gdk component publish command should check if the component version already exists in the S3 bucket before attempting to upload. If it exists, the command should either:
Fail gracefully with a clear message indicating the version already exists.
Provide a flag (e.g., --overwrite) to explicitly allow the user to overwrite the object.
Actual Behavior
The command overwrites the existing S3 artifact, causing an inconsistency between the S3 object and the Greengrass component. The subsequent CreateComponentVersion API call fails, and deployments fail with a botocore.errorfactory.ConflictException followed by an ARTIFACT_CHECKSUM_MISMATCH error.
Proposed Solutions
Pre-upload Check: Before uploading the artifact, use the head_object method to check if the file already exists in the S3 bucket. If it does, and a --force or --overwrite flag is not present, skip the upload and provide a user-friendly error message.
Relevant code location: https://github.com/aws-greengrass/aws-greengrass-gdk-cli/blob/main/gdk/commands/component/PublishCommand.py#L84-L87
Conditional Writes: Investigate using S3 conditional write headers, such as if-none-match or if-match.
Note: As per the boto3 documentation, these headers are not directly supported by the S3Transfer class used for uploads. This may require a different approach or a custom implementation using the put_object API call directly.
Relevant Links
Problem Statement
The gdk component publish command does not check for the existence of a component's artifact version in the S3 bucket before uploading. This behavior results in the command overwriting the S3 object (or creating a new version if versioning is enabled). While the S3 upload itself might succeed, the subsequent
CreateComponentVersioncall fails, and any deployments using the component version result in anARTIFACT_CHECKSUM_MISMATCHerror.This happens because the gdk-cli first uploads the artifact to S3 and then attempts to create the Greengrass component version using the CreateComponentVersion API. If a component with the same name and version already exists in the AWS account, the API call will fail, but the S3 artifact has already been overwritten, corrupting the link between the S3 object and the Greengrass component.
To Reproduce
Run gdk component publish for a component with a specific version (e.g., 1.0.0).
Run gdk component publish again for the exact same component and version.
Observe the following error in the terminal:
If a Greengrass deployment is attempted with this component version, it will fail with an
ARTIFACT_CHECKSUM_MISMATCHerror.Expected Behavior
The gdk component publish command should check if the component version already exists in the S3 bucket before attempting to upload. If it exists, the command should either:
Fail gracefully with a clear message indicating the version already exists.
Provide a flag (e.g., --overwrite) to explicitly allow the user to overwrite the object.
Actual Behavior
The command overwrites the existing S3 artifact, causing an inconsistency between the S3 object and the Greengrass component. The subsequent
CreateComponentVersionAPI call fails, and deployments fail with abotocore.errorfactory.ConflictExceptionfollowed by anARTIFACT_CHECKSUM_MISMATCHerror.Proposed Solutions
Pre-upload Check: Before uploading the artifact, use the head_object method to check if the file already exists in the S3 bucket. If it does, and a
--forceor--overwriteflag is not present, skip the upload and provide a user-friendly error message.Relevant code location: https://github.com/aws-greengrass/aws-greengrass-gdk-cli/blob/main/gdk/commands/component/PublishCommand.py#L84-L87
Conditional Writes: Investigate using S3 conditional write headers, such as
if-none-matchorif-match.Note: As per the boto3 documentation, these headers are not directly supported by the
S3Transferclass used for uploads. This may require a different approach or a custom implementation using theput_objectAPI call directly.Relevant Links
PublishCommand.py: https://github.com/aws-greengrass/aws-greengrass-gdk-cli/blob/main/gdk/commands/component/PublishCommand.py#L84-L87put-objectdocumentation: https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object.htmlboto3.s3.transfer.S3Transferdocumentation on allowed arguments: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/customizations/s3.html#boto3.s3.transfer.S3Transfer.ALLOWED_UPLOAD_ARGS