feat(ecr): add ECR Batch 1 — repository CRUD, tags, policies#717
Merged
vieiralucas merged 7 commits intomainfrom Apr 23, 2026
Merged
feat(ecr): add ECR Batch 1 — repository CRUD, tags, policies#717vieiralucas merged 7 commits intomainfrom
vieiralucas merged 7 commits intomainfrom
Conversation
Batch 1 of 4 in the ECR buildout. LocalStack gates ECR behind its paid Pro tier and Moto can't speak the OCI v2 Distribution protocol at all, so real `docker push` / `docker pull` is broken across both tools. This batch lays the foundation: a new `fakecloud-ecr` crate, the full Smithy model pinned in `aws-models/ecr.json`, JSON-1.1 dispatch (`X-Amz-Target: AmazonEC2ContainerRegistry_V20150921.*`), multi-account state, snapshot persistence, and the 11 repository-level operations. Operations: - CreateRepository / DeleteRepository / DescribeRepositories - PutImageTagMutability / PutImageScanningConfiguration - SetRepositoryPolicy / GetRepositoryPolicy / DeleteRepositoryPolicy - TagResource / UntagResource / ListTagsForResource Coverage: - 11/58 ECR ops implemented, 11 pass 100% of their conformance variants (`cargo run -p fakecloud-conformance --release -- run --services ecr`). - 6 E2E tests + 1 persistence round-trip test, all green. - Conformance baseline updated; other services hold at 100%. - Introspection endpoint `/_fakecloud/ecr/repositories` exposes repository metadata without leaking runtime internals. Image + layer ops land in Batch 2, OCI v2 Distribution + real `docker push` in Batch 3, lifecycle + scanning + cross-service in Batch 4.
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
4 issues found across 26 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="crates/fakecloud-ecr/src/state.rs">
<violation number="1" location="crates/fakecloud-ecr/src/state.rs:153">
P2: `RegistryScanningConfiguration::default()` currently produces an empty `scan_type`, but this state expects the default to be `"BASIC"`.
This can return incorrect registry scanning configuration after account creation/reset.</violation>
</file>
<file name="crates/fakecloud-ecr/src/service.rs">
<violation number="1" location="crates/fakecloud-ecr/src/service.rs:189">
P2: Repository name validation is incomplete and accepts names that violate the documented ECR pattern.</violation>
<violation number="2" location="crates/fakecloud-ecr/src/service.rs:383">
P2: `DescribeRepositories` validates `maxResults` but does not apply it, so responses can exceed the requested limit.</violation>
</file>
<file name="crates/fakecloud-server/src/reset.rs">
<violation number="1" location="crates/fakecloud-server/src/reset.rs:116">
P2: `reset_service("ecr")` keeps non-default accounts instead of fully resetting the multi-account container. Use `MultiAccountState::reset()` to match reset semantics used by other services.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
`apigwv2_closure_routes_exist` was sending empty / minimal bodies to several operations whose handlers enforce the Smithy `@required` contract. The test was only checking that the routes existed, but the handlers had since gained input validation that rejects those requests with 400, so the test started failing regardless of route wiring. Fixes: - UpdateApiMapping: include ApiId (required). - CreateVpcLink: include SubnetIds (required). - CreateRoutingRule / PutRoutingRule: include Actions, Conditions, Priority. - CreateModel: include Schema (required). - ExportApi: include outputType query param (required). - CreatePortal: include Authorization, EndpointConfiguration, PortalContent. - CreatePortalProduct: use DisplayName (required), not Name. - PutPortalProductSharingPolicy: include PolicyDocument. - CreateProductPage: include DisplayContent object. - CreateProductRestEndpointPage: include RestEndpointIdentifier.
- RegistryScanningConfiguration::default() now returns scanType=BASIC
to match AWS's default for new registries (was previously an empty
string, which would corrupt Get/PutRegistryScanningConfiguration
responses after account creation or reset).
- DescribeRepositories now actually applies maxResults and threads a
nextToken through for pagination instead of validating the value
and then ignoring it.
- Repository name validation now enforces the full AWS regex
(?:[a-z0-9]+(?:[._-][a-z0-9]+)*/)*[a-z0-9]+(?:[._-][a-z0-9]+)*
via a byte-level state machine. Rejects consecutive separators,
trailing/leading separators, empty segments, and non-lowercase
characters. Unit tests lock the accepted/rejected cases.
- reset_service("ecr") now calls MultiAccountState::reset() like every
other service, dropping non-default accounts instead of preserving
them with their state cleared.
There was a problem hiding this comment.
4 issues found across 4 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="crates/fakecloud-ecr/src/service.rs">
<violation number="1" location="crates/fakecloud-ecr/src/service.rs:392">
P2: `DescribeRepositories` does not apply AWS’s default page size (100) when `maxResults` is omitted.</violation>
<violation number="2" location="crates/fakecloud-ecr/src/service.rs:397">
P2: Invalid `nextToken` values are silently treated as offset `0` instead of returning a parameter error.</violation>
</file>
<file name="crates/fakecloud-conformance/tests/apigatewayv2.rs">
<violation number="1" location="crates/fakecloud-conformance/tests/apigatewayv2.rs:981">
P2: Populate the required `DisplayContent` fields here; an empty object is not a valid `CreateProductPage` request.</violation>
<violation number="2" location="crates/fakecloud-conformance/tests/apigatewayv2.rs:1019">
P2: Fill in the required `RestEndpointIdentifier.IdentifierParts` fields; an empty object is not a valid `CreateProductRestEndpointPage` request.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
The e2e-partition-check job was hitting `No space left on device` while `cargo nextest list` compiled the E2E test suite — the runner disk was full of cached build artifacts, Android SDKs, .NET runtimes, etc. Use the same jlumbroso/free-disk-space action the lambda matrix jobs use to reclaim ~15GB before the nextest compile.
The adding of aws-sdk-ecr to fakecloud-testkit pushed the nextest compile over the runner's disk budget for matrix jobs like lambda-api and general-1/2 that previously fit. Run the free-disk-space step on every E2E matrix shard, not just the lambda-runtimes / container cliché ones.
- DescribeRepositories now applies AWS's documented default page size of 100 when maxResults is absent (was returning all repos). - Invalid nextToken strings now return InvalidContinuationTokenException instead of silently falling back to offset 0. - apigwv2 closure-routes test now sends Smithy-correct DisplayContent (Body + Title) and RestEndpointIdentifier.IdentifierParts (Method, Path, RestApiId, Stage) per the model's @required traits.
This was referenced Apr 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
docker push/docker pulldo not work across either tool.Scope of this PR (Batch 1 of 4):
CreateRepository,DeleteRepository,DescribeRepositoriesPutImageTagMutability,PutImageScanningConfigurationSetRepositoryPolicy,GetRepositoryPolicy,DeleteRepositoryPolicyTagResource,UntagResource,ListTagsForResourceCoverage numbers (
cargo run -p fakecloud-conformance --release -- run --services ecr):maxResultsrange)Follow-up batches
PutImage,BatchGetImage,BatchCheckLayerAvailability,InitiateLayerUpload,UploadLayerPart,CompleteLayerUpload,GetDownloadUrlForLayer, etc.) + EventBridge emission on push/delete./v2/...endpoints) +GetAuthorizationToken+ Basic-Auth — the differentiator that makes realdocker pushwork.Test plan
cargo build --workspacecargo fmt --checkcargo clippy --workspace --all-targets -- -D warningscargo test -p fakecloud-e2e --test ecr --test ecr_persistence— 7 passingcargo test -p fakecloud-conformance --test ecr— 11 passingcargo run -p fakecloud-conformance --release -- check— no regressions/_fakecloud/ecr/repositoriesreturns expected shapeSummary by cubic
Adds ECR Batch 1 with repository CRUD, tagging, and policies via the new
fakecloud-ecrservice, plus stricter validation, default paging, and proper token errors. This sets up multi-account state and persistence for future image ops and OCI push/pull.New Features
fakecloud-ecrcrate with JSON-1.1 routing (AmazonEC2ContainerRegistry_V20150921), snapshot persistence, and reset hooks; exposed via/_fakecloud/ecr/repositories.Bug Fixes
maxResults(default 100), supportsnextToken, and returnsInvalidContinuationTokenExceptionfor bad tokens; default registry scanning to BASIC.reset_service("ecr")now drops non-default accounts for consistency.nexteststderr on errors.Written for commit fdebea8. Summary will update on new commits.