mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-11-02 01:09:48 +00:00
bf3c5e3dba946821e6a4ae14b7f765094de5e6ed
2776 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
bf3c5e3dba | fix: refuse ECR policy texts that are omitted or outside the model's length before parsing them (#1402) | ||
|
|
9a571a7438 | fix(ecs): refuse DeleteCluster without a cluster instead of deleting the default cluster (#1408) | ||
|
|
045816a44d | fix(ecr): refuse a tag with no Value on CreateRepository and TagResource (#1404) | ||
|
|
f6686b5436 |
feat(sts): refuse to mint credentials for an account that is not ACTIVE (#1410)
* feat(sts): refuse to mint credentials for an account that is not ACTIVE * feat(sts): log a refused mint for an account that is not ACTIVE |
||
|
|
b034f3b2e9 |
fix(sqs): bring up loopback in the SQS guest before its store starts (#1409)
The guest's SQS nats-server listens on 127.0.0.1 and the worker dials it there, but the kernel leaves lo down, so the store failed to bind and the worker never polled. Also correct the stale CA comment in init. |
||
|
|
3d387c839d | fix: return AWS's task-definition defaults, registeredAt and deregisteredAt, and tags only with include TAGS (#1398) | ||
|
|
a5c07f37fd | fix: return createdAt, startedAt and stoppedAt from ECS DescribeTasks (#1401) | ||
|
|
c50cc2512a |
fix: fail ELBv2 Describe calls for unknown target groups, load balancer names and listener LB ARNs (#1405)
DescribeTargetGroups rejects a malformed target group ARN with ValidationError and reports a missing group with AWS's message, DescribeLoadBalancers fails with LoadBalancerNotFound for an unknown name, and DescribeListeners fails with LoadBalancerNotFound for an unknown load balancer ARN. The EKS cluster NLB lookup treats the new not-found as absent. |
||
|
|
5310c82e95 | fix: report EBS encryption by default from the platform's key posture and refuse disabling it (#1397) | ||
|
|
943f191bf3 | fix: refuse an ECR encryptionConfiguration that omits encryptionType (#1399) | ||
|
|
671a8a9ff5 |
feat(sqs): fresh single-node SQS in one system microVM (#1389)
* feat(sqs): run queue and message owners in the worker by signed pull The SQS worker's ready step now opens the queue and message owners on its dedicated store and serves owner calls it pulls from its node's gateway over the existing instance-role channel (PollWork, CompleteWork). Each poll and post is authorized against the current worker identity, and a result is accepted only from the identity that took the work. No payload crosses platform NATS. A receipt-signing key is created on the worker disk only under the first-store decision that creates the store key, and its fingerprint is bound in the store; a missing or changed key refuses to serve. Received messages are released only when the gateway proves the caller left; receives are capped so a worst-case result fits one post. The public relay is not registered in production. * fix: harden SQS relay results and bound pending bytes Unavailable outranks client faults when encoding owner errors, and wire errors carry fixed text only, never owner or backend text. The ingress rejects incomplete or mismatched success results as unavailable, and the relay bounds total pending input bytes as well as request count. Adds tests of every relay action against real owners, the receive claim limit, release, faulting work, the receipt-key fingerprint marker and the poll loop through gateway failures. * fix: refuse SQS serving outside a single-node host cluster DescribeStore now reports the gateway's declared cluster node count, and the worker refuses to serve, before reading keys, connecting or creating any store state, unless that count is exactly one. A gateway that reports no count reads as zero and is refused. * feat(sqs): record a store server key pin once per store instance Add the store role and its internal actions so the bound store instance can learn its claim and record the public pin of its TLS server key, once, without the platform holding the private key. The worker sees the store as bound only after a pin exists and must receive a valid pin. * refactor(sqs): serve store server keys from a separate capability Keep the worker Stores interface unchanged and give the store guest's actions their own ServerKeys dependency, so existing Stores fakes need no store-key methods. * feat(sqs): launch the store with a mgmt NIC, CA and scoped store role The store now boots with the region, gateway URL and the daemon's own cluster CA, a mgmt NIC to reach the gateway, and an sqsStoreRole profile granted only the store's two internal actions, so it can authenticate its server key pin. A store record that predates these fields refuses to relaunch; its volume is kept. * feat(sqs): keep the store TLS server key on its disk and record its pin The store image gains sqs-store-key, run after the data disk is mounted. It loads or creates a P-256 server key under the disk's tls directory, records only the key's public pin with the gateway as the bound store instance, and writes a self-signed certificate for it to the run directory. nats-server then requires TLS 1.3 with that key. A record for another volume, a recorded pin with a missing key, or a key that does not match the recorded pin refuses the store; no key is regenerated and nothing on the disk is deleted. Launch-not-yet-bound and lost replies are retried. The store role vocabulary moves to contracts/sqs/v1 so the guest agent does not import a domain. * feat(sqs): pin the worker's store connection to the recorded server key The worker's readiness check and serving connection now use TLS 1.3 and accept only the store server key whose pin the bound store recorded with the gateway. The pin is checked before the worker key or any queue or message data is sent, and on every reconnect. A store with another key, a plaintext store or a malformed pin is refused as final. The worker NKey client authentication is unchanged. The host still holds the store's data disk key, so the pin does not protect the store from a privileged host. * fix(sqs): retry store key bootstrap and track guest binary sources The store's server key check moves from sysinit into the respawned run step: a gateway or IMDS outage exits after a pause so init retries it, without remounting or creating a new key, while a missing, changed or wrong-store key is recorded as refused and never retried. Stop also ends a running key helper before unmounting. The guest helper and worker binaries now depend on every main-module package dir and file they link, from go list, so edits, additions, deletions and renames all rebuild them. * feat(sqs): operator enable and status with a signed ingress test Add a per-Region SQS service record (disabled by default, pinned to one node, refused on multi-node clusters before any write), gate the relay on it, and expose `spx admin sqs enable` and `spx admin sqs status`. The gateway now hands queued work to the polling worker and reports whether one is polling. The public SQS service stays unregistered in production until its capability profile is reviewed. An integration test registers it through the harness and drives real SigV4 and IAM requests to a real worker for create, send, receive and delete, asserting no SQS body crosses platform NATS. * fix(sqs): report readiness only from observed component state Status now reports whether the tenant SQS API is registered on this gateway and is never Ready while it is not. The worker stops polling while its store connection is down, so a worker that lost its store drops out of the gateway's poller window instead of looking healthy. * wip: sqs model inventory * wip: sqs public registration * wip: sqs registration review fixes * fix(sqs): refuse pre-API store and worker records on enable A store or worker record this release creates now carries an explicit contract. enable reads both records without creating a bucket and refuses any record without it before it writes desired state or launches anything; status names the record and is never Ready. A worker replacement keeps its predecessor's contract, since it reuses the same data volume. Missing metadata is only ever grounds to refuse: nothing is upgraded, inspected, emptied, replaced or deleted. Upgrading a pre-API dev install is not supported. * fix(sqs): describe the enable refusal as an unsupported launch contract A missing or unknown contract proves neither when a record was written nor that it predates authenticated bootstrap: an older writer can drop a newer field, and a future contract is not pre-API. The refusal is unchanged; its message, status field and docs now name a missing or unsupported launch contract and say any existing volume is kept. * wip: port reviewed SQS serving path onto dev without the store VM * wip: single SQS system VM * fix(sqs): retry receipt bootstrap under supervision and drop store install path Run the receipt-key boot step from the respawned store service so a transient gateway or IMDS outage recovers without a reboot; final key and volume refusals stay refused. Remove the separate store image install and staging path from setup. * fix(sqs): align worker ready config fields * fix(sqs): stop an in-progress boot before unmounting the worker disk The receipt-key boot step ran as an unrecorded child of the store shell, so shutdown stopped only the shell and could unmount the disk under a boot still talking to the gateway. Record the boot child like the other guest processes and stop it before unmounting; a survivor keeps the disk mounted. * fix(sqs): record the boot child before its stopping check The parent wrote boot.pid only after starting the child, so a shutdown in that gap could unmount under an unrecorded boot. The child now records itself and checks stopping before it runs sqs-worker boot. |
||
|
|
529acf7ef6 |
chore: bump the go-dependencies group with 16 updates (#1376)
* chore: bump the go-dependencies group with 16 updates Bumps the go-dependencies group with 16 updates: | Package | From | To | | --- | --- | --- | | [github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2) | `1.47.4` | `1.47.5` | | [github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream](https://github.com/aws/aws-sdk-go-v2) | `1.7.24` | `1.7.25` | | [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2) | `1.33.9` | `1.33.12` | | [github.com/aws/aws-sdk-go-v2/credentials](https://github.com/aws/aws-sdk-go-v2) | `1.20.9` | `1.20.12` | | [github.com/aws/aws-sdk-go-v2/feature/ec2/imds](https://github.com/aws/aws-sdk-go-v2) | `1.20.3` | `1.20.5` | | [github.com/aws/aws-sdk-go-v2/service/lambda](https://github.com/aws/aws-sdk-go-v2) | `1.113.3` | `1.113.4` | | [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) | `1.114.4` | `1.114.6` | | [github.com/aws/aws-sdk-go-v2/service/sqs](https://github.com/aws/aws-sdk-go-v2) | `1.52.6` | `1.52.7` | | [github.com/aws/smithy-go](https://github.com/aws/smithy-go) | `1.28.6` | `1.28.7` | | [github.com/nats-io/nats-server/v2](https://github.com/nats-io/nats-server) | `2.15.1` | `2.15.2` | | [github.com/nats-io/nats.go](https://github.com/nats-io/nats.go) | `1.54.0` | `1.55.0` | | [go.etcd.io/etcd/api/v3](https://github.com/etcd-io/etcd) | `3.5.35` | `3.7.3` | | [go.etcd.io/etcd/client/pkg/v3](https://github.com/etcd-io/etcd) | `3.5.35` | `3.7.3` | | [go.etcd.io/etcd/client/v3](https://github.com/etcd-io/etcd) | `3.5.35` | `3.7.3` | | [go.yaml.in/yaml/v3](https://github.com/yaml/go-yaml) | `3.0.5` | `3.0.6` | | [google.golang.org/grpc](https://github.com/grpc/grpc-go) | `1.83.2` | `1.85.0` | Updates `github.com/aws/aws-sdk-go-v2` from 1.47.4 to 1.47.5 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.47.4...v1.47.5) Updates `github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream` from 1.7.24 to 1.7.25 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/aws/protocol/eventstream/v1.7.24...aws/protocol/eventstream/v1.7.25) Updates `github.com/aws/aws-sdk-go-v2/config` from 1.33.9 to 1.33.12 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.33.9...config/v1.33.12) Updates `github.com/aws/aws-sdk-go-v2/credentials` from 1.20.9 to 1.20.12 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/kms/v1.20.9...service/sso/v1.20.12) Updates `github.com/aws/aws-sdk-go-v2/feature/ec2/imds` from 1.20.3 to 1.20.5 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/v1.20.3...service/mq/v1.20.5) Updates `github.com/aws/aws-sdk-go-v2/service/lambda` from 1.113.3 to 1.113.4 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.113.3...service/s3/v1.113.4) Updates `github.com/aws/aws-sdk-go-v2/service/s3` from 1.114.4 to 1.114.6 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.114.4...service/s3/v1.114.6) Updates `github.com/aws/aws-sdk-go-v2/service/sqs` from 1.52.6 to 1.52.7 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/ssm/v1.52.6...service/sqs/v1.52.7) Updates `github.com/aws/smithy-go` from 1.28.6 to 1.28.7 - [Release notes](https://github.com/aws/smithy-go/releases) - [Changelog](https://github.com/aws/smithy-go/blob/main/CHANGELOG.md) - [Commits](https://github.com/aws/smithy-go/compare/v1.28.6...v1.28.7) Updates `github.com/nats-io/nats-server/v2` from 2.15.1 to 2.15.2 - [Release notes](https://github.com/nats-io/nats-server/releases) - [Changelog](https://github.com/nats-io/nats-server/blob/main/RELEASES.md) - [Commits](https://github.com/nats-io/nats-server/compare/v2.15.1...v2.15.2) Updates `github.com/nats-io/nats.go` from 1.54.0 to 1.55.0 - [Release notes](https://github.com/nats-io/nats.go/releases) - [Commits](https://github.com/nats-io/nats.go/compare/v1.54.0...v1.55.0) Updates `go.etcd.io/etcd/api/v3` from 3.5.35 to 3.7.3 - [Release notes](https://github.com/etcd-io/etcd/releases) - [Commits](https://github.com/etcd-io/etcd/compare/v3.5.35...v3.7.3) Updates `go.etcd.io/etcd/client/pkg/v3` from 3.5.35 to 3.7.3 - [Release notes](https://github.com/etcd-io/etcd/releases) - [Commits](https://github.com/etcd-io/etcd/compare/v3.5.35...v3.7.3) Updates `go.etcd.io/etcd/client/v3` from 3.5.35 to 3.7.3 - [Release notes](https://github.com/etcd-io/etcd/releases) - [Commits](https://github.com/etcd-io/etcd/compare/v3.5.35...v3.7.3) Updates `go.yaml.in/yaml/v3` from 3.0.5 to 3.0.6 - [Commits](https://github.com/yaml/go-yaml/compare/v3.0.5...v3.0.6) Updates `google.golang.org/grpc` from 1.83.2 to 1.85.0 - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.83.2...v1.85.0) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go-v2 dependency-version: 1.47.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream dependency-version: 1.7.25 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: github.com/aws/aws-sdk-go-v2/config dependency-version: 1.33.12 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: github.com/aws/aws-sdk-go-v2/credentials dependency-version: 1.20.12 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: github.com/aws/aws-sdk-go-v2/feature/ec2/imds dependency-version: 1.20.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: github.com/aws/aws-sdk-go-v2/service/lambda dependency-version: 1.113.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: github.com/aws/aws-sdk-go-v2/service/s3 dependency-version: 1.114.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: github.com/aws/aws-sdk-go-v2/service/sqs dependency-version: 1.52.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: github.com/aws/smithy-go dependency-version: 1.28.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: github.com/nats-io/nats-server/v2 dependency-version: 2.15.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: github.com/nats-io/nats.go dependency-version: 1.55.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-dependencies - dependency-name: go.etcd.io/etcd/api/v3 dependency-version: 3.7.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-dependencies - dependency-name: go.etcd.io/etcd/client/pkg/v3 dependency-version: 3.7.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-dependencies - dependency-name: go.etcd.io/etcd/client/v3 dependency-version: 3.7.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-dependencies - dependency-name: go.yaml.in/yaml/v3 dependency-version: 3.0.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go-dependencies - dependency-name: google.golang.org/grpc dependency-version: 1.85.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: go-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> * fix: embed UnimplementedClusterServer in fakeetcd for etcd v3.7 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Julian Sommer <115516918+juliansommer@users.noreply.github.com> |
||
|
|
44f71e95d8 | chore: fix ui lint issues | ||
|
|
d6c9efb8c3 |
chore: bump the npm-dependencies group (#1377)
Bumps the npm-dependencies group in /spinifex/runtime/roles/spinifexui/frontend with 30 updates: | Package | From | To | | --- | --- | --- | | [@aws-sdk/client-acm](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-acm) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/client-bedrock](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-bedrock) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/client-bedrock-agent](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-bedrock-agent) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/client-bedrock-agent-runtime](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-bedrock-agent-runtime) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/client-bedrock-runtime](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-bedrock-runtime) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/client-ec2](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-ec2) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/client-ecr](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-ecr) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/client-ecs](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-ecs) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/client-eks](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-eks) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/client-elastic-load-balancing-v2](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-elastic-load-balancing-v2) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/client-iam](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-iam) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/client-rds](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-rds) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/client-route-53](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-route-53) | `3.1156.0` | `3.1159.0` | | [@aws-sdk/client-s3](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-s3) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/client-sts](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/clients/client-sts) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/lib-storage](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/lib/lib-storage) | `3.1155.0` | `3.1159.0` | | [@aws-sdk/xhr-http-handler](https://github.com/aws/aws-sdk-js-v3/tree/HEAD/packages/xhr-http-handler) | `3.1155.0` | `3.1159.0` | | [@hookform/resolvers](https://github.com/react-hook-form/resolvers) | `6.0.0` | `6.0.2` | | [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) | `5.104.5` | `5.105.0` | | [@tanstack/react-router](https://github.com/TanStack/router/tree/HEAD/packages/react-router) | `1.170.45` | `1.170.46` | | [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `1.61.0` | `1.63.0` | | [react-hook-form](https://github.com/react-hook-form/react-hook-form) | `7.90.0` | `7.91.0` | | [react-resizable-panels](https://github.com/bvaughn/react-resizable-panels) | `4.15.0` | `4.15.1` | | [@tanstack/eslint-plugin-query](https://github.com/TanStack/query/tree/HEAD/packages/eslint-plugin-query) | `5.104.5` | `5.105.0` | | [@tanstack/router-plugin](https://github.com/TanStack/router/tree/HEAD/packages/router-plugin) | `1.168.47` | `1.168.48` | | [oxc-transform-react](https://github.com/oxc-project/oxc/tree/HEAD/napi/transform-react) | `0.155.0` | `0.156.0` | | [oxfmt](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt) | `0.74.0` | `0.75.0` | | [oxlint](https://github.com/oxc-project/oxc/tree/HEAD/npm/oxlint) | `1.89.0` | `1.90.0` | | [oxlint-tsgolint](https://github.com/oxc-project/tsgolint) | `7.0.2004` | `7.0.2005` | | [ultracite](https://github.com/haydenbleasel/ultracite) | `8.0.1` | `8.1.0` | Updates `@aws-sdk/client-acm` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-acm/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-acm) Updates `@aws-sdk/client-bedrock` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-bedrock/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-bedrock) Updates `@aws-sdk/client-bedrock-agent` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-bedrock-agent/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-bedrock-agent) Updates `@aws-sdk/client-bedrock-agent-runtime` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-bedrock-agent-runtime/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-bedrock-agent-runtime) Updates `@aws-sdk/client-bedrock-runtime` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-bedrock-runtime/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-bedrock-runtime) Updates `@aws-sdk/client-ec2` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-ec2/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-ec2) Updates `@aws-sdk/client-ecr` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-ecr/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-ecr) Updates `@aws-sdk/client-ecs` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-ecs/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-ecs) Updates `@aws-sdk/client-eks` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-eks/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-eks) Updates `@aws-sdk/client-elastic-load-balancing-v2` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-elastic-load-balancing-v2/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-elastic-load-balancing-v2) Updates `@aws-sdk/client-iam` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-iam/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-iam) Updates `@aws-sdk/client-rds` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-rds/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-rds) Updates `@aws-sdk/client-route-53` from 3.1156.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-route-53/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-route-53) Updates `@aws-sdk/client-s3` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-s3/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-s3) Updates `@aws-sdk/client-sts` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/clients/client-sts/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/clients/client-sts) Updates `@aws-sdk/lib-storage` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/lib/lib-storage/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/lib/lib-storage) Updates `@aws-sdk/xhr-http-handler` from 3.1155.0 to 3.1159.0 - [Release notes](https://github.com/aws/aws-sdk-js-v3/releases) - [Changelog](https://github.com/aws/aws-sdk-js-v3/blob/main/packages/xhr-http-handler/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-js-v3/commits/v3.1159.0/packages/xhr-http-handler) Updates `@hookform/resolvers` from 6.0.0 to 6.0.2 - [Release notes](https://github.com/react-hook-form/resolvers/releases) - [Commits](https://github.com/react-hook-form/resolvers/compare/v6.0.0...v6.0.2) Updates `@tanstack/react-query` from 5.104.5 to 5.105.0 - [Release notes](https://github.com/TanStack/query/releases) - [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md) - [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.105.0/packages/react-query) Updates `@tanstack/react-router` from 1.170.45 to 1.170.46 - [Release notes](https://github.com/TanStack/router/releases) - [Changelog](https://github.com/TanStack/router/blob/main/packages/react-router/CHANGELOG.md) - [Commits](https://github.com/TanStack/router/commits/@tanstack/react-router@1.170.46/packages/react-router) Updates `lucide-react` from 1.61.0 to 1.63.0 - [Release notes](https://github.com/lucide-icons/lucide/releases) - [Commits](https://github.com/lucide-icons/lucide/commits/1.63.0/packages/lucide-react) Updates `react-hook-form` from 7.90.0 to 7.91.0 - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.90.0...v7.91.0) Updates `react-resizable-panels` from 4.15.0 to 4.15.1 - [Release notes](https://github.com/bvaughn/react-resizable-panels/releases) - [Changelog](https://github.com/bvaughn/react-resizable-panels/blob/main/CHANGELOG.md) - [Commits](https://github.com/bvaughn/react-resizable-panels/compare/4.15.0...4.15.1) Updates `@tanstack/eslint-plugin-query` from 5.104.5 to 5.105.0 - [Release notes](https://github.com/TanStack/query/releases) - [Changelog](https://github.com/TanStack/query/blob/main/packages/eslint-plugin-query/CHANGELOG.md) - [Commits](https://github.com/TanStack/query/commits/@tanstack/eslint-plugin-query@5.105.0/packages/eslint-plugin-query) Updates `@tanstack/router-plugin` from 1.168.47 to 1.168.48 - [Release notes](https://github.com/TanStack/router/releases) - [Changelog](https://github.com/TanStack/router/blob/main/packages/router-plugin/CHANGELOG.md) - [Commits](https://github.com/TanStack/router/commits/@tanstack/router-plugin@1.168.48/packages/router-plugin) Updates `oxc-transform-react` from 0.155.0 to 0.156.0 - [Release notes](https://github.com/oxc-project/oxc/releases) - [Changelog](https://github.com/oxc-project/oxc/blob/main/napi/transform-react/CHANGELOG.md) - [Commits](https://github.com/oxc-project/oxc/commits/crates_v0.156.0/napi/transform-react) Updates `oxfmt` from 0.74.0 to 0.75.0 - [Release notes](https://github.com/oxc-project/oxc/releases) - [Changelog](https://github.com/oxc-project/oxc/blob/main/npm/oxfmt/CHANGELOG.md) - [Commits](https://github.com/oxc-project/oxc/commits/oxfmt_v0.75.0/npm/oxfmt) Updates `oxlint` from 1.89.0 to 1.90.0 - [Release notes](https://github.com/oxc-project/oxc/releases) - [Changelog](https://github.com/oxc-project/oxc/blob/main/npm/oxlint/CHANGELOG.md) - [Commits](https://github.com/oxc-project/oxc/commits/oxlint_v1.90.0/npm/oxlint) Updates `oxlint-tsgolint` from 7.0.2004 to 7.0.2005 - [Release notes](https://github.com/oxc-project/tsgolint/releases) - [Commits](https://github.com/oxc-project/tsgolint/compare/v7.0.2004...v7.0.2005) Updates `ultracite` from 8.0.1 to 8.1.0 - [Release notes](https://github.com/haydenbleasel/ultracite/releases) - [Commits](https://github.com/haydenbleasel/ultracite/compare/ultracite@8.0.1...ultracite@8.1.0) --- updated-dependencies: - dependency-name: "@aws-sdk/client-acm" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-bedrock" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-bedrock-agent" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-bedrock-agent-runtime" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-bedrock-runtime" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-ec2" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-ecr" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-ecs" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-eks" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-elastic-load-balancing-v2" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-iam" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-rds" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-route-53" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-s3" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/client-sts" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/lib-storage" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@aws-sdk/xhr-http-handler" dependency-version: 3.1159.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@hookform/resolvers" dependency-version: 6.0.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-dependencies - dependency-name: "@tanstack/react-query" dependency-version: 5.105.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@tanstack/react-router" dependency-version: 1.170.46 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-dependencies - dependency-name: lucide-react dependency-version: 1.63.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: react-hook-form dependency-version: 7.91.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: react-resizable-panels dependency-version: 4.15.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-dependencies - dependency-name: "@tanstack/eslint-plugin-query" dependency-version: 5.105.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: "@tanstack/router-plugin" dependency-version: 1.168.48 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: npm-dependencies - dependency-name: oxc-transform-react dependency-version: 0.156.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: oxfmt dependency-version: 0.75.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: oxlint dependency-version: 1.90.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm-dependencies - dependency-name: oxlint-tsgolint dependency-version: 7.0.2005 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: npm-dependencies - dependency-name: ultracite dependency-version: 8.1.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: npm-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
bbd4e84f15 |
chore: bump the docker-images group across 3 directories with 3 updates (#1375)
Bumps the docker-images group with 1 update in the /build directory: golang. Bumps the docker-images group with 2 updates in the /docs/terraform-workbooks/demo-app directory: golang and distroless/static. Bumps the docker-images group with 1 update in the /scripts directory: debian. Updates `golang` from `972b411` to `d9b6a1b` Updates `golang` from `f2c872b` to `d200d2d` Updates `distroless/static` from `18f4cc2` to `25ac8f0` Updates `debian` from `62bd423` to `f6b08b0` --- updated-dependencies: - dependency-name: golang dependency-version: 1.27.3-bookworm dependency-type: direct:production update-type: version-update:semver-patch dependency-group: docker-images - dependency-name: golang dependency-version: 1.27.3-alpine dependency-type: direct:production update-type: version-update:semver-patch dependency-group: docker-images - dependency-name: distroless/static dependency-version: nonroot dependency-type: direct:production dependency-group: docker-images - dependency-name: debian dependency-version: trixie-slim dependency-type: direct:production dependency-group: docker-images ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> |
||
|
|
14f6ea83d0 |
fix: root-cause every flaky unit test from the last 14 days of the PR gate (#1395)
* fix(test): never hand KillProcess a PID a real process can hold * fix(iam): queue same-record writers so a looping self-write cannot starve DetachUserPolicy * fix(ecs-agent): report RUNNING before starting container exit-waits * fix(rds): wait for the lease-loss cancellation instead of sleeping in the takeover test * fix(cli): name the account when the follow deadline lands mid-poll * test(imagecatalog): never answer from the deadline fixture * test(nats): order Gather StopOnFirst frames causally, not by sleep * fix(ec2/key): find a key pair by name past an unreadable metadata record * fix(accountlifecycle): re-list at the drain deadline so a just-deleted resource is not stuck * fix(eks): give only the exhausting subtest the short SG delete budget * fix(eks): stop healthz and nodegroup Ready-gate tests racing fixed wall-clock windows * fix(test): let in-process NATS clusters bind their own route ports * fix(objectstore): list the memory store in S3 key order with real paging * test(viperblock): create a fresh volume on every run of the local-state test * test(ochre): close router streams so drained tests release their admission slot * test(cli): restore shared cobra flags after each ochre command test * test(daemon): keep shared-JetStream, metric and RSS tests correct on repeat runs * fix(ochre): let a warm-up probe stop so a test's poller cannot hit a later test's server * test(cli): pin the package's cluster size so a multi-node config load cannot strand later fixtures |
||
|
|
30b8c24776 |
feat(accountlifecycle): seal quota overrides during account teardown (#1390)
* feat(admission): add the quota override seal capability contract * feat(awsgw): serve the quota override seal capability per node * refactor(accountlifecycle): parameterise the seal capability probe and add the quota one * test(accountlifecycle): pin the probe wire shape against both capability contracts * feat(accountlifecycle): seal the quota override record during account teardown * docs: record the quota override seal contract and teardown behaviour * docs: fill in the quota override seal PR number in the package boundary migration |
||
|
|
8855d60c94 |
fix(ci): release the ISO build's root-owned cache when the ISO cells end (#1393)
The ISO cells build the rootfs as root inside the workspace and only cleaned it at the start of their own job, so the next job on the same runner from any workflow failed its checkout on files it could not remove. |
||
|
|
d420bff09c |
fix(eks): delete the Node of a terminated nodegroup worker (#1392)
* fix(eks): delete the Node of a terminated nodegroup worker K3s runs no AWS cloud provider, and its own reports every instance as existing, so a worker terminated by DeleteNodegroup, scale-down or reclaim stayed a NotReady Node forever. Its pods stayed bound to it, and once most Nodes were NotReady the node lifecycle controller stopped evicting, leaving metrics-server on a dead Node. Add an internal-workers route the control plane pulls the cluster's live nodegroup workers from, and a mulga-eks-node-gc agent on every server that deletes a nodegroup Node only when it is not Ready and its instance is no longer one of those workers, as the AWS cloud controller does. * test(e2e): check the live worker's Node and wait out nodegroup deletes WorkerNodeReady accepted any Ready Node, the tolerate-all DaemonSet check dropped pods with no Ready condition, and nodegroup cleanup returned before the nodegroup was gone. Scope the Ready check to the CPIsolation nodegroup, count a pod with no Ready condition as not Ready, wait for each nodegroup delete, and assert that deleted nodegroups leave no Node behind. * test(integration): account for the internal ListInternalWorkers route in the cross-tenant table |
||
|
|
6c3d6c6be3 |
fix(setup): keep NetworkManager from replacing the resolved stub link (#1391)
NetworkManager restarted while /etc/resolv.conf is a plain file runs in rc-manager=symlink mode and writes resolv.conf on its first DNS update, which can land after the installer links the stub. Write a conf.d drop-in (dns=systemd-resolved, rc-manager=unmanaged) before the restart, refuse a later file that overrides rc-manager, wait for NetworkManager to settle, and assert the link holds with bounded relinks. A rerun after an older handover adds the drop-in, reloads NetworkManager and relinks the stub. |
||
|
|
2466a9c8af |
fix: stamp the ENI owner in the attach write and release a failed LB's VM (#1388)
* test: pin the ENI owner stamp and failed-LB cleanup contracts Failing tests: an ENI update after the caller's own write must survive a lagging replica read, an unwritable owner stamp must fail the system launch, and the reaper must terminate the failed LB's own VM only. * fix: stamp the ENI owner in the attach write and release a failed LB's VM A lagging-replica read before the owner stamp's compare-and-swap lost the stamp, leaving a system VM that IMDS could never resolve. - AttachENIWithOwner records the instance owner in the attach write. - ENI read-modify-writes re-read and re-apply on a revision conflict, bounded, and report the store error to the caller's log. - A system launch whose ENI cannot be attached or stamped fails and cleans up the VM. - The reaper that marks an LB failed terminates that LB's own VM and detaches its ENIs. * fix: log ENI write retries and exhaustion An Info line on a write that succeeds after a revision conflict and an Error line when the bounded retries run out, so the sink can count both. * test: cover an internal ALB in a private subnet and report the ENI attachment owner DescribeNetworkInterfaces now returns Attachment.InstanceOwnerId when the record has one, as AWS does, so the owner stamp is observable. The e2e launches an internal ALB in a VPC with no internet gateway and checks the owner, the private address and in-VPC traffic. The ENI write error log now reports the real attempt count, so a non-conflict store error is not counted as an exhausted retry. * revert: stop reporting the ENI attachment owner through Describe AWS always returns Attachment.InstanceOwnerId, so reporting it only for system-owned ENIs adds a divergence. The e2e now relies on the LB reaching active with a healthy target, which needs the owner stamp to resolve. |
||
|
|
f37776384c | docs: fill in the 11d-2 PR number in the package boundary migration (#1386) | ||
|
|
ea1ca38c52 |
fix: boot LB and SQS worker microvms with PCIe NICs (#1385)
* test: direct-boot LB and SQS worker NICs must be virtio-net-pci on microvm pcie=on * fix: boot LB and SQS worker microvms on PCIe with virtio-net-pci NICs virtio-mmio devices share level-triggered IRQ lines and a NIC's RX path stalled on them. The direct-boot machine gets pcie=on, so NICs are virtio-net-pci with MSI-X, and the virtio_mmio.device= kernel args go. IsMMIO is now the transport check (false with pcie=on) and IsMicrovm the machine check. Data volumes keep their serial and ID on virtio-blk-pci. The LB guest console loglevel is raised to 7. * refactor: trim microvmMachineType comment * docs: describe direct-boot microVM NICs and data volumes on PCIe |
||
|
|
8add7c03b3 |
refactor: move the gateway into ingress/aws/pipeline and delete it (11d-2) (#1384)
* refactor: move the gateway into ingress/aws/pipeline and retire the gateway layering rows The gateway's request pipeline joins the packages it already consumed. Operation inventory moves to ingress/aws/dispatch. Files keep their names; only the package line, the import paths and the now-redundant pipeline qualifier change. The layering rows for the gateway root are removed: the package is under ingress, so R2 binds it, and the daemon-direction test now asserts R2 rejects runtime, operator and domain imports. An empty registry_helper_test.go was dropped rather than moved. * refactor: rename pipeline.GatewayConfig to pipeline.Config * docs: update the design and package boundary docs for the gateway move * docs: point the EKS add-on lifecycle evidence at the tests' current files |
||
|
|
34f7b4d8e5 |
fix(vm): reboot by relaunching QEMU after a clean guest shutdown (#1383)
RebootInstances powered the guest down under -action shutdown=pause and then ran system_reset + cont in the same QEMU process. On some hosts the reset left the guest silent in firmware with QMP still answering, while a fresh QEMU on the same volumes always booted. A reboot now shuts the guest down over ACPI (forcing it off after 60s, as before), ends that QEMU, and starts a fresh one on the same mounted volumes, taps, IMDS datapath and identity, the way nova's soft reboot and Proxmox's qm reboot do. The instance stays running in Describe, no hooks fire, the console log is appended rather than truncated, and the existing QMP client is reconnected in place so the heartbeat carries on. A relaunched guest that writes nothing to its console within 60s has its run state, vCPUs, vCPU thread states and registers (sampled twice) logged, and if it has printed before, its QEMU is replaced once more. A relaunch that cannot start goes to crash recovery. Stop, terminate and hot-plug wait for a relaunch in flight so volumes are never sealed under a process being started. Guest-initiated reboots stay an in-process reset. The daemon now logs the host kernel, QEMU version and the OVMF package and checksum at start, and every reboot relaunch carries them. |
||
|
|
8e5680f77f |
fix(e2e): harden nightly e2e against seven false-red signatures; release auto-assigned IP before stopped (#1381)
* fix(vm): release an auto-assigned public IP before a stop publishes stopped * fix(e2e): skip a TryReady caller once the suite's SSH datapath is marked broken * fix(e2e): skip a catalog entry whose third-party mirror is unreachable, still fail on a non-2xx * fix(e2e): retry the diskperf fio install with backoff before calling it an infra fault * fix(e2e): make the storagefault root-load check observe the load it started * fix(ci): give the single suite a 40m budget and the nightly cells that run it 60m * fix(ci): fail a nightly cell fast when a hypervisor it provisions on is out of disk |
||
|
|
cf31090043 |
fix(fence): stop the writer first, deliver the fence notice, kill the fenced guest (#1382)
Three defects in the fence path made partition recovery fail: - onVolumeLeaseLost read the lease holder before killing nbdkit, with no deadline, spending the 5s margin between local validity and the server TTL. The kill now comes first and the read is bounded at 2s. - The fence notice was one NATS publish, lost when the node's NATS restarts mid-fence. It is now a request repeated until the daemon acknowledges, dropped once the volume is exported here again. - A fenced guest got a 20s ACPI powerdown, a 20s pidfile wait and a SIGTERM, keeping QEMU alive while a survivor relaunched it. It is now SIGKILLed, and resumeAfterIOError never resumes a fenced guest. |
||
|
|
0604472ffe |
fix(vpcd): converge every node's VPC ingress routes from intent (#1380)
The routed-NAT host route to a VPC CIDR was installed only by the vpcd that received the IGW attach event, which goes through a queue group, and by whichever node won a leased drift pass. Every other node waited for the five-minute resync, and with two VPCs on one CIDR each node kept whichever route it met first. Each node now runs a host ingress loop outside the drift lease. It reads intent and the gateway LRPs on every intent write, on a nudge from the local IGW hooks and every 30s, installs or repoints the routes, and prunes tagged routes no attached VPC holds. A shared CIDR goes to the bootstrap VPC, then to the lowest VPC ID. |
||
|
|
956b830f18 |
fix(firewall): keep conntrack running while the host policy is disarmed (#1379)
The kernel tracks connections only while some rule uses conntrack. With inet spinifex_filter unloaded nothing tracked, so OVN RAFT links formed while disarmed (or before the daemon's first arm) were first seen mid-stream at arm time. With tcp_loose a packet from the server end became a new flow from peer:6643/6644 to an ephemeral port and hit the drop rule, and RAFT lost its leader. Add table inet spinifex_conntrack (accept-only) and keep it loaded on every node: setup.sh loads it at install, the boot unit loads it unconditionally, firstboot loads it before OVN, and disable swaps the policy for it in one transaction instead of turning conntrack off. |
||
|
|
f0a704cfcd |
refactor: move the gateway's public routes, admin wiring and unread config out (11d-1) (#1378)
* test: pin the order of the unauthenticated mounts against SigV4 and the throttle
* refactor: mount the OIDC and registry routes through a public-routes hook
* refactor: take the admin registration name and request-id context as gateway config
* refactor: move node discovery out of the gateway into the awsgw role
* refactor: drop the gateway config fields production never reads (Config, RootCAs, InternalSuffix)
* refactor: drop the gateway Version and Commit config fields
* refactor: compose the production gateway config in one tested function
* refactor: drop the gateway IAMService, STSService, NATSConn and ExpectedNodes config fields
Production never reads them: composeGateway builds Policy and Readiness from
its own inputs. Tests that used the config as a carrier now keep those
collaborators in gwfix.Deps, recorded per config with gwfix.WithDeps and read
back with gwfix.DepsOf. Gateway non-test code now imports nothing under
domains/, runtime/ or operator/.
Test edits are setup only: 153 GatewayConfig literals in 45 files had the four
keys moved into gwfix.WithDeps(..., gwfix.Deps{...}), and 113 field reads
became gwfix.DepsOf(x).{IAM,STS,NATS,Nodes}. No assertion changed.
Script 1, literal rewrite (balanced-brace scanner, keys moved out of the
literal):
import re,sys,subprocess,os
KEYS={'IAMService':'IAM','STSService':'STS','NATSConn':'NATS','ExpectedNodes':'Nodes'}
def scan_close(s,i):
# s[i]=='{' ; return index of matching '}' ; skips strings, runes, comments
d=0;n=len(s);k=i
while k<n:
c=s[k]
if c=='"':
k+=1
while s[k]!='"':
k+= 2 if s[k]=='\\' else 1
elif c=='`':
k=s.index('`',k+1)
elif c=="'":
k+=1
while s[k]!="'":
k+= 2 if s[k]=='\\' else 1
elif s.startswith('//',k):
k=s.index('\n',k)
continue
elif s.startswith('/*',k):
k=s.index('*/',k)+1
elif c in '{([': d+=1
elif c in '})]':
d-=1
if d==0: return k
k+=1
raise Exception('unbalanced')
def split_top(body):
parts=[];d=0;start=0;k=0;n=len(body)
while k<n:
c=body[k]
if c=='"':
k+=1
while body[k]!='"': k+= 2 if body[k]=='\\' else 1
elif c=='`': k=body.index('`',k+1)
elif c=="'":
k+=1
while body[k]!="'": k+= 2 if body[k]=='\\' else 1
elif body.startswith('//',k):
k=body.index('\n',k); continue
elif body.startswith('/*',k): k=body.index('*/',k)+1
elif c in '{([': d+=1
elif c in '})]': d-=1
elif c==',' and d==0:
parts.append(body[start:k]); start=k+1
k+=1
parts.append(body[start:])
return parts
changed={}
files=[l for l in subprocess.check_output(['git','ls-files','*.go']).decode().split() if os.path.exists(l)]
SKIP={'spinifex/gateway/gateway.go','spinifex/runtime/roles/awsgw/compose.go','spinifex/runtime/roles/awsgw/awsgw.go'}
lit=re.compile(r'(&?)((?:gateway\.)?GatewayConfig)\{')
total=0
for f in files:
if f in SKIP: continue
s=open(f).read()
if 'GatewayConfig{' not in s: continue
out=[];pos=0;cnt=0
for m in lit.finditer(s):
if m.start()<pos: continue
o=m.end()-1
c=scan_close(s,o)
body=s[o+1:c]
parts=split_top(body)
keep=[];moved=[]
for p in parts:
km=re.match(r'\s*(IAMService|STSService|NATSConn|ExpectedNodes)\s*:\s*(.*)$',p,re.S)
if km: moved.append((KEYS[km.group(1)],km.group(2).strip()))
else: keep.append(p)
if not moved: continue
# rebuild
kb=','.join(keep)
if kb.strip()=='' : kb=''
elif not kb.rstrip().endswith('\n') and '\n' in body: pass
d=', '.join(f'{k}: {v}' for k,v in moved)
new=f'gwfix.WithDeps({m.group(1)}{m.group(2)}{{{kb}}}, gwfix.Deps{{{d}}})'
if not m.group(1): new=f'gwfix.WithDeps(&{m.group(2)}{{{kb}}}, gwfix.Deps{{{d}}})' # value literals flagged below
out.append((m.start(),c+1,new)); pos=c+1; cnt+=1
if not m.group(1): print('VALUE LITERAL',f,s.count('\n',0,m.start())+1)
if not out: continue
r=[];last=0
for a,b,n in out:
r.append(s[last:a]);r.append(n);last=b
r.append(s[last:])
s2=''.join(r)
if 'testkit/gwfix"' not in s2:
s2=re.sub(r'import \(\n','import (\n\t"github.com/mulgadc/spinifex/internal/testkit/gwfix"\n',s2,1)
open(f,'w').write(s2); total+=cnt; changed[f]=cnt
print('literals rewritten',total,'files',len(changed))
Script 2, read rewrite (driven by the compiler's "has no field or method"
errors for the type, so only GatewayConfig receivers are touched):
import re,subprocess,sys,collections
M={'IAMService':'IAM','STSService':'STS','NATSConn':'NATS','ExpectedNodes':'Nodes'}
def run():
env=dict(__import__('os').environ,GOWORK='off')
out=''
for tags,pk in [('',['./spinifex/gateway','./spinifex/runtime/roles/awsgw/...']),('integration',['./tests/integration/...'])]:
cmd=['go','test','-count=1','-run','NONE_X','-gcflags=-e']+(['-tags',tags] if tags else [])+pk
r=subprocess.run(cmd,capture_output=True,text=True,env=env)
out+=r.stdout+r.stderr
return out
fixed=0
for it in range(8):
out=run()
errs=re.findall(r'^(\S+\.go):(\d+):(\d+): (.*?) undefined \(type (\*?(?:gateway\.)?GatewayConfig) has no field or method (\w+)\)',out,re.M)
if not errs:
print(out[-3000:]); break
byfile=collections.defaultdict(list)
for f,l,c,expr,t,fld in errs: byfile[f].append((int(l),int(c),expr,fld))
for f,es in byfile.items():
lines=open(f).read().split('\n')
for l,c,expr,fld in sorted(set(es),reverse=True):
line=lines[l-1]
# expr like 'gw.IAMService' or 'x.y.IAMService'
new=f'gwfix.DepsOf({expr[:-len(fld)-1]}).{M[fld]}'
if expr not in line: print('MISS',f,l,expr); continue
lines[l-1]=line.replace(expr,new)
fixed+=1
s='\n'.join(lines)
if 'testkit/gwfix"' not in s:
s=re.sub(r'import \(\n','import (\n\t"github.com/mulgadc/spinifex/internal/testkit/gwfix"\n',s,count=1)
open(f,'w').write(s)
print('read sites fixed',fixed)
* docs: record the gateway mount hooks and config-field removal in the package boundary migration
* docs: fill in the 11d-1 PR number in the package boundary migration
|
||
|
|
83ec8b512d |
refactor: move service-named pipeline behaviour into registration metadata (ADR-0002:S9) (#1374)
* test: pin service-keyed gateway behaviour before it moves to registration metadata * refactor: declare the XML throttle code on the registration The pipeline picked Throttling for iam, sts, eks and route53 by name. EKS is a JSON registration and never reached that arm, so it is not carried over. * refactor: declare the XML error shape on the registration EC2 and the operator surface declare the EC2 shape. S3 is not served here, so the composition declares its scope traits and a rejected S3 request keeps S3's body. * refactor: declare the global signing region on the registration * refactor: supply the unsigned web-identity exchange as a pre-auth handler STS composition now hands the pipeline a dispatch.PreAuth. The gateway no longer recognises STS or the action by name, and the layering allowlist row for gateway -> sts/awsapi is paid off. * refactor: declare payload-body scopes as traits The action recovery for a rejected request skipped S3 by name. The composition now declares the S3 scope as carrying object data, and the gateway reads the trait. * test: wire the integration harness through PreAuth |
||
|
|
1cfaf15c9d |
fix: EKS control-plane VMs are not Kubernetes Nodes (#1373)
* test: pin control-plane no-agent config, etcd member removal and CP isolation e2e * test: tighten CP isolation e2e and assert a logged prune failure * fix: run EKS control planes without a k3s agent and prune etcd members directly Control-plane VMs no longer register as Nodes, so pods cannot schedule onto a network that cannot reach the workers or the advertised endpoint. With no Node to delete, a replaced peer's etcd member is removed by a new eks-etcd-member helper that matches exactly one member by peer-URL host. * fix: refuse to remove the local etcd member by ID, not only by IP Self-protection no longer depends on first boot deriving its own address: the helper asks the connected endpoint for its member ID and refuses a match on it. * test(e2e): align EKS suite with control planes that are not Nodes Assert zero Nodes and delivered addon objects before any nodegroup. Check Ready worker, metrics APIService, addon deletion and pod logs once a worker exists, scoping logs to Ready nodes and waiting 10m for metrics-server to reschedule. * docs: EKS control-plane hosts are not Kubernetes Nodes Document that kubectl get nodes lists workers only, add upgrade notes for existing clusters, and list the eks-etcd-member helper. * docs: explain why addon manifests keep the CriticalAddonsOnly toleration Comment-only. The toleration stays for clusters created before control-plane hosts stopped registering as Nodes. * test: cover the etcd member client and CLI against a TLS fake etcd The real etcd client and the command had no tests, leaving the PR below the diff coverage threshold. A fake etcd serving the Cluster and Maintenance APIs over mutual TLS drives the client with the K3s certificate layout, and main becomes a testable run function. |
||
|
|
be99d9c4fe |
test: move remaining service and verdict tests out of gateway (#1372)
* refactor: move gateway auth fixtures to runtime-free gwfix package * refactor: move ACM gateway tests to awsgw * refactor: keep gateway-internal ACM tests in gateway and drop test-only exports * refactor: move RDS gateway tests to awsgw * refactor: move ELBv2 gateway tests to awsgw * refactor: move IAM gateway tests to awsgw * refactor: move STS gateway tests to awsgw * refactor: move tagging gateway tests to awsgw * refactor: move operator and bedrock gateway tests to awsgw * refactor: move ECR gateway tests to awsgw * refactor: move ECS and EKS gateway tests to awsgw * refactor: move EC2 gateway tests to awsgw * refactor: move credential verdict tests to awsgw * refactor: move policy-gate dispatch tests to their service packages * refactor: move checkPolicy verdict tests to policyauth * refactor: run gateway tests on a fake verifier, real auth only for listed verdict tests |
||
|
|
e3a44893fa |
fix: bound the console's instance-type payload and stop polling it (#1371)
* fix: bound the console's instance-type payload and stop polling it DescribeInstanceTypes with capacity=true returned one entry per free slot per node: 3,528,765 bytes of XML for 50 distinct types on prod, refetched every five seconds. The response was sized by free capacity, so the emptier the cluster the larger it got, and at 44,346 slots it exceeded the NATS maximum payload and the console reported no compute at all. The listing now names each admissible type once. The free-slot figure crosses as a number through a new GetInstanceTypeCapacity action, open to any account because the launch form a tenant uses is what needs it. The catalogue query no longer polls, and the EKS and ECS dialogs read it only when open. The gateway negotiates gzip inside the SigV4 group, which excludes the OCI Distribution registry structurally. A response is compressed only if the client offered gzip, the handler declared neither a length nor an encoding, the content type is neither streaming nor already compressed, the status carries a body, and 1 KiB was written before any flush. An unknown capacity figure no longer caps the count at 1. The launch decides, and RunInstances answers InsufficientInstanceCapacity if it cannot. * test: read the free slot count from its own action in the console e2e Two e2e tests encoded capacity as repeated instance-type entries, so one expected a caption the deduplicated listing can no longer produce. The fixture answers GetInstanceTypeCapacity instead, which lets a test give the catalogue and the figure different answers. A third test covers the case the change introduces: a session whose policy does not grant the action reads no figure, so the form offers the type with no capacity caption and leaves the launch enabled. The committed bundle is rebuilt, which rehashes every chunk reaching the two query modules. |
||
|
|
1d3c2a7cbd |
fix: bound the capacity describe reply by instance-type count, not free slots (#1368)
* fix: bound the capacity describe reply by instance-type count, not free slots A node answering `DescribeInstanceTypes` with `capacity=true` sent one full copy of an instance type's description per free slot, so the reply grew with how much capacity the host had free. At 1344 bytes per slot the four-node production cluster, holding no guests, produced 874 slots and a reply over the 1 MB NATS maximum payload. Every node's reply was dropped, the gateway collected zero frames, and it returned an empty list as a success. The console reads an empty capacity list as no capacity and refuses every launch, which is how a cluster with hundreds of free vCPU reported "No compute available". The emptier the cluster, the more likely the failure, which is the opposite of what the shape should be. A node now returns each admissible type once with the number of instances of it the node can take, so its reply is bounded by the size of the instance-type catalogue and not by free capacity. On the production catalogue that is 84 KB for 62 types whatever the slot count, against 59 MB for the same reply on a large idle host under the old shape. The gateway sums the per-type counts across nodes and expands them on the last hop, because the client SDK drops response fields it does not model and the console displays the figure to the customer. A capacity fan-out that collected no frames now returns a retryable ServiceUnavailable. Reporting an empty list as a success is what turned a transport failure into a false statement about the cluster. Two tests pin the shape: the node reply for an idle 4096-vCPU host stays under the NATS payload limit, and a capacity fan-out with no responders does not return an empty success. * test: cover the console against a real cluster, and pin the capacity banner The console has never been exercised against a real control plane. `playwright.config.ts` pins `localhost:3101` and `:3102` and intercepts every API call, so the suite cannot be pointed at a cluster and cannot see a defect whose whole content is what the control plane actually sends. That is why an idle production cluster came to tell customers it had no compute: the capacity listing was dropped in transport, the empty result read as no capacity, and nothing in CI could reach the page that says so. `playwright.live.config.ts` runs the same console against a cluster named by `SPX_CONSOLE_URL`, signing in with `SPX_ACCESS_KEY_ID` and `SPX_SECRET_ACCESS_KEY`. It starts no server, mocks nothing, runs one worker because it launches real guests, and is never part of `pnpm e2e`. The suite signs in, asserts a cluster with free capacity offers instance types rather than reporting none, reads the per-type capacity figure, launches an instance and waits for `running`, reads its live metric graphs, terminates it in a `finally` block, and loads the nine listing pages a customer reaches from the sidebar. Three tests in the mocked suite pin the banner's own logic, which is cheap and catches the UI side of the same failure: the form offers what the capacity listing reports, it shows the free slot count for the selected type, and an account with genuinely no capacity is told so and cannot submit. The third passes on the current code and is the one that documents why the banner exists at all. * test: correct three live-console selectors found by running it against prod The first run of the live suite was 11 passed and 2 failed, both in the suite rather than in the console. The dashboard check looked for node status on `/`, where it is not shown. It now loads `/nodes` and asserts the `Resource usage by node` and `Instance type capacity` tables, which is where the daemon reports a node's own capacity. The OS tile's radio is `sr-only` behind the distribution logo, so `check()` failed its actionability test on the `<img>` covering it. The click goes to the enclosing `<label>` instead and the browser forwards it. The terminate dialog holds its confirm disabled until the phrase is typed, so the teardown waited out its timeout on a disabled button and left the instance running. The helper types `terminate` first. With those three corrected the launch, running, live-metrics and terminate path passes against the production console in 34 s. |
||
|
|
9c99312f74 | feat(ui): enforce ADR-0016 with guard tests and move dialog forms into FormPanel (#1369) | ||
|
|
9e3a7b9c8c |
fix: let a snapshot go once every volume cloned from it is already deleting (#1370)
* fix: let a snapshot go once every volume cloned from it is already deleting DeleteVolume now records State=deleting and leaves the teardown to the reclaim reaper, so a clone stays listed after the tenant has deleted it. DeleteSnapshot counted that clone as still reading the snapshot and refused with InvalidSnapshot.InUse, which broke DeleteDBSnapshot after deleting the DB instance restored from it and left the retained source volume behind. A deleting volume's teardown removes only its own objects and nothing moves it out of deleting, so it no longer holds the snapshot's chunks. * test(e2e/rds): delete a snapshot straight after the instance restored from it The subtest deleted the source instance between the two, which gave the volume reclaim reaper time to finish the restored volume on a fast node and hid the refusal the nightly hit. Deleting the snapshot immediately makes the regression deterministic. The release wait now covers a full reclaim sweep: since deletion became asynchronous a released volume is gone only after the reaper's next pass. |
||
|
|
c3bed5535b |
test: move per-service gateway tests into their domains (#1366)
* refactor: one authorization gate in ingress/aws/pipeline
The key merge and the caller guards move out of the gateway so tests that
drive a registration directly use the same gate as the pipeline.
* test: run ACM handler and policy tests in domains/acm/awsapi
Adds internal/testkit/gwtest, which invokes a registration through the
pipeline's own authorization gate with real policy evaluation.
* test: share policy assertion helpers through gwtest
* test: run ELBv2 handler and policy tests in domains/elbv2/awsapi
* refactor: one actor projection in ingress/aws/pipeline
* test: run RDS handler and policy tests in domains/rds/awsapi
* test: run ECS handler and policy tests in domains/ecs/awsapi
* test: assert the exact policy gate verdict in gwtest
* test: run EKS authz and wire tests in domains/eks/awsapi
* test: run IAM authorization tests in domains/iam/awsapi
The policy-driven DeleteRole and AddRoleToInstanceProfile tests run in the IAM package through gwtest, with PassRoleTo shared. The HTTP-handler, examples and signed-pipeline tests stay in gateway.
* test: run ECR authorization tests in domains/ecr/awsapi
* test: run ECR repository, image and lifecycle-preview tests in domains/ecr/awsapi
* test: run ECR dispatch error tests in domains/ecr/awsapi
* test: run Bedrock authorization tests in domains/ochre/awsapi
* refactor: move EC2 authz tests into domains/ec2/awsapi
* test: restore the ECS scope-table completeness gate in domains/ecs/awsapi
* Revert "test: restore the ECS scope-table completeness gate in domains/ecs/awsapi"
This reverts commit
|
||
|
|
4468f13e53 |
docs: add a diagram of a Vultr deployment to the guide (#1367)
Shows deploy-vultr.sh building a private Vultr VPC with one node or three, the nodes clustering over the private network for the control plane, EBS and S3, Spinifex calling the Vultr API for reserved IPs, and the AWS services running across the fleet. |
||
|
|
8a71854463 |
docs: tidy the Vultr guide for publication (#1365)
Drops the horizontal rules the docs site rendered as stray text, links the AWS CLI install page, captions each screenshot, shows the expected spx get nodes output for three nodes, explains what a three-node deployment protects against, and simplifies the limits to the sizing and quorum a reader needs. |
||
|
|
e155bcf155 |
feat(sqs): queue and Lambda-facing message API foundation (#1364)
* feat(sqs): queue and Lambda-facing message API foundation Adds the SQS JSON 1.0 adapter (unregistered in production) with queue create, lookup, attributes, list, tags and the message operations a Lambda poller uses: SendMessage(Batch), ReceiveMessage with long polling and attribute selection, DeleteMessage(Batch) and ChangeMessageVisibility(Batch), backed by the queue record owner and the JetStream message store. String and Binary message attributes are validated, stored and checksummed; Number attributes are refused until AWS behaviour is confirmed. * test(sqs): poller lifecycle through the message owners Covers receive, release, redelivery, delete, visibility extension, queue binding of receipt handles and long polling against the real queue and JetStream message stores, from the message package itself. * test(sqs): move SDK coverage from the gateway to the SQS domain Drives the registration through dispatch.Invocation over the real queue and message owners, so the gateway package carries no SQS changes. |
||
|
|
7aa76c5bd6 |
refactor: gateway request record and capabilities (ADR-0002:S7, S8) (#1363)
* test: pin gateway pipeline order, request ids and region * refactor: carry request facts in one ingress request record * fix: seal the request principal once * refactor: build the caller ARN once in credverify * refactor: gateway takes policy and admission as capabilities * refactor: gateway takes cluster readiness as a capability * chore: gofmt GatewayConfig field alignment * docs: record slice 11a request record and capabilities * docs: add PR number to slice 11a migration row * refactor: move pipeline capability interfaces to ingress/aws/pipeline |
||
|
|
b80d4e2371 | ci: ask PR authors whether Mulga design needs to change (#1362) | ||
|
|
b4dd606104 |
feat: run Spinifex on Vultr, with failover, workbooks and the fixes they needed (#1361)
* feat: Vultr reserved-IP provider and floating external-address pool Adds a source="vultr" external pool backed by Vultr reserved IPs: an API client pinned by captured responses, an in-memory fake with the measured semantics, and a floating allocator that creates, claims, reconciles and releases labelled addresses. OCI and Vultr claims now share one AddressClaimer pass. Also fixes the host firewall dropping guest IMDS when imds_host_meta_ip is set, by matching the pre-DNAT destination, and arms the Spinifex firewall in place of an active ufw. * fix: detach a Vultr reserved IP before deleting it Vultr was measured refusing delete of an attached address with 400 "Unable to detach subnet", so release, rollback and reconcile now detach first. A first claim after allocation logs at info rather than warn. * fix: release the auto-assigned public IP an Elastic IP displaces AssociateAddress restamped the ENI with the EIP and never handed back the address launch had assigned. Nothing referred to it afterwards, so it stayed allocated for good, and on a cloud pool every associate left a billed address. AWS releases it on associate; withdraw its NAT rule and release it, scoped to the ENI, leaving any address another associated EIP holds alone. * fix: retry Vultr's refused detach on reserved-IP detach and delete Vultr has answered a detach with 400 "Unable to detach subnet" and accepted the same detach moments later. Surfacing it left the address for reconcile to collect, up to twenty billed minutes later; retry it like a 5xx instead. * fix: stop reporting the released launch address after an EIP is disassociated Associating an EIP now releases the auto-assigned public IP, but the stored instance kept its launch stamp, and DescribeInstances fell back to it once the EIP was disassociated. The public-IP change handler now moves the stamp with the runtime address. * feat: add a Vultr deploy script for a single-node Spinifex on a VX VM deploy.sh up/destroy/status drives Terraform for the VPC and VM, installs and forms Spinifex over SSH, copies the API key to the node rather than through user-data, and sweeps boot volumes and reserved IPs Terraform does not own. Cloud-init keeps needrestart off the Spinifex, OVS and OVN units and disables unattended upgrades on these disposable hosts. * feat: form a three-node Vultr deployment with install-node.sh over the VPC Each node comes up as an armed single node, the state install-node.sh forms from, with the cluster and Geneve planes on the VPC NIC. The pool and every node's provider_host_id go on each node after formation. * fix: read the pinned host key with ssh-keygen -F when forming a Vultr cluster ssh_config hashes known_hosts entries by default on Debian, so a grep for the address found nothing and set -e ended the run without a message. * docs: add the Vultr guide, one command to deploy one or three nodes and one to remove them * docs: drop the failover write note from the Vultr guide * fix: keep needrestart from restarting the Spinifex, OVS and OVN units Guest QEMU runs in spinifex-daemon's cgroup, so needrestart charged QEMU's replaced libraries to the daemon and restarted it after every dpkg run. The restart never cleared them, so an unattended upgrade ran the unit into its start limit and left the control plane down. setup.sh now writes /etc/needrestart/conf.d/90-spinifex.conf, deselecting spinifex-, ovs-, ovsdb-, ovn- and openvswitch- units. needrestart still lists them, so restarting after an upgrade stays the operator's choice. * chore: drop the Vultr cloud-init needrestart override now setup.sh writes it * docs: replace the Vultr guide's apt upgrade warning now the installer keeps needrestart off the stack * docs: install the Vultr guide's build from the dev channel until Vultr support is released * fix: answer ARP for Vultr reserved IPs on bare metal Vultr routes a reserved IP to a VM by MAC but ARPs for it on a bare-metal server's public segment, and a Vultr pool gave vpcd neither a gateway nor a bind bridge to proxy-ARP on, so nothing answered and no traffic arrived. A Vultr pool now proxy-ARPs on the interface the node routes the internet through. setup.sh installs arping, which the gratuitous ARP already called. * feat: deploy Spinifex on Vultr bare metal, renamed deploy-vultr.sh A vbm- plan creates bare-metal servers, one or three. Without --name the deployment writes the AWS profile spinifex, up prints every node's address and the API key allowlist, credentials and ssh subcommands are added, no AMI is imported unless --image is given, and OpenTofu or Terraform is used. The host key is pinned only once cloud-init is done, since bare metal first answers SSH from Vultr's installer with a different key. * docs: rework the Vultr guide into the OCI guide's flow, with bare metal * fix: restamp LaunchTime when a stopped or recovered instance relaunches The pending watchdog times a launch from LaunchTime, which still held the original launch. An instance recovered from a failed node, or started more than five minutes after it was first launched, was terminated as stuck in pending seconds after QEMU started. AWS restamps LaunchTime on every start. * feat: spread the nginx-alb workbook across nodes, and power Vultr nodes off and on from deploy-vultr.sh The workbook takes server_count and placement_strategy, so three web servers can run one per node. Its README now matches the template (public subnets, no NAT gateway) and the diagram shows the spread. deploy-vultr.sh gains stop and start, which halt and start a node through the Vultr API. * fix: let a terminate finish tearing down before the reaper calls it wedged OrphanQEMUReaper finalized any shutting-down instance whose QEMU had exited, on the premise that a live terminate still has a live QEMU. A terminate is still deleting volumes, releasing its IP and leaving its placement group for tens of seconds after QEMU exits, so the instance was reported terminated first. Terraform then deleted the placement group and got InvalidPlacementGroup.InUse. The reconcile now waits two minutes from shutting-down, well inside the ten-minute stuck-terminate backstop. * fix: release an ovs-vswitchd left in flow-restore-wait after a node boots ovn-controller clears flow-restore-wait once its flows are installed and sets it again straight after. When both writes reach ovs-vswitchd as one update, it only sees true, starts no upcall threads and forwards nothing. Seen on Vultr bare metal after a hard power-off: instances recovered onto the rebooted node ran but were unreachable. vpcd now clears the flag on any node held that way for a minute, longer than ovs-ctl's own restore takes. * docs: add a resiliency test to the Vultr guide and the nginx-alb workbook The Vultr guide gains step 8, which spreads three web servers across a three-node deployment, powers a node off and back on, and shows what was measured on VMs and bare metal. The workbook gains the same test as step 6. The guide's table of contents is repaired, and its limits now cover losing two nodes and recovery inside a spread placement group. * fix: never terminate an instance that has run because a relaunch failed The pending watchdog terminated any instance pending past five minutes, and terminating deletes DeleteOnTermination volumes. A start of a stopped instance, a recovery from a failed node and a daemon relaunch all pass through pending, so a slow one destroyed an existing instance and its root disk. On Vultr a recovered instance was terminated seconds after QEMU started and its root volume deleted. An instance is now marked FirstLaunch from RunInstances until it first reaches running, cleared before the running state is written. The watchdog acts only on first launches, as AWS terminates only a launch that never ran. MarkFailed refuses to terminate any other instance and marks it recovery-failed instead, which keeps its volumes, ENI and addresses and shows it as stopped. A claimed relaunch is never a first launch. Invariant tests pin ADR-0003:S7. The instancerecovery e2e suite gains a test that ages its guest past the watchdog before recovering it, then stops and starts it, and requires the instance, its root volume and the data on it to survive both. * feat: run the Terraform workbooks against a Vultr deployment on demand, and show the Vultr portal in the guide e2e-cloudvendor-vultr.yml is dispatch-only. It builds the ref, deploys it with deploy-vultr.sh on one or three VMs or bare-metal servers, runs the published workbooks from node1 with the same driver as the hypervisor nightly and OCI, and destroys the deployment, failing if anything is left billing. It needs one secret, VULTR_API_KEY, and generates its SSH key per run. The guide gains screenshots of the API key's access control list and of the nodes in the Vultr portal, and its portal navigation now matches. * fix: install setup.sh on Vultr nodes when the tarball does not carry it build-install-artifacts.sh writes setup.sh beside the tarball, so a node installed from its tarball had no /usr/local/share/spinifex/setup.sh and arming the firewall failed. * fix: pass the remote command after the destination in the Vultr e2e driver * fix: run each workbook in the cluster's own region The workbook driver passed no region, so every workbook used its default, ap-southeast-2, and on a cluster in any other region every request failed SignatureDoesNotMatch. It now passes the region of the node's spinifex profile. * feat: count a node's vCPUs as online CPUs and reserve by host size (ADR-0015) A node counted physical cores, collapsing SMT threads, and held back a fixed 2 vCPU, so a 16-thread host offered 6 vCPU to instances. A vCPU is now one online CPU, as AWS counts it: a thread with SMT on, a core with SMT off or on ARM. The OS and Spinifex keep 1 CPU up to 8, 2 up to 16, 4 up to 63 and 8 from 64, and the rest is allocated one to one. The existing overrides stay operator-only. Invariant tests pin every tier boundary. * docs: state the Vultr guide's sizing under the online-CPU count * docs: drop an unmeasured EKS sizing claim from the Vultr README * fix: let a guest reach an Elastic IP hosted on its own node A guest's packet to an EIP on its own node left its VPC from the transit range, was masqueraded to the transit host address, and went back into OVN, which exempts that range from EIP DNAT, so it was never answered. On Vultr an EKS worker could not reach its control plane's endpoint, so it never joined. AWS lets an instance reach a public address in its own VPC. Hairpinned transit traffic now jumps to SPX-EIP-HAIRPIN, above the egress MASQUERADE, where each EIP's rule sends it from the uplink address, as the host's own traffic to the EIP already is. The rule follows the EIP's ingress plumbing in and out, and anything else returns to the MASQUERADE. * fix: resolve Spinifex's LB and EKS names on Vultr nodes Vultr's Ubuntu image writes a static resolv.conf naming Vultr's resolvers, so lookups bypassed the split DNS Spinifex configures in systemd-resolved and an EKS endpoint name did not resolve on the node. deploy-vultr.sh points resolv.conf at the resolved stub, as stock Ubuntu does. * test: prove a guest reaches an EIP on its own node in the natuplink e2e The nat-single cells run it with a public pool, so the hairpin path that left EKS workers unable to reach their control plane on Vultr is now covered nightly. * docs: record the natuplink hairpin check in the e2e coverage index * fix: keep each Vultr node's logs when an e2e run fails The driver destroyed a node whose install failed together with the log that said why. It now copies /root/*.log from every node into the run's artifacts before the teardown, and the workflow uploads them. --------- |
||
|
|
e709717fde |
fix: launch EKS workers with IMDS hop limit 2 and honour launch template metadata options (#1360)
* test: pin EKS worker IMDS metadata options and launch template resolution * fix: launch EKS workers with IMDS hop limit 2 and honour launch template metadata options * fix: default unset launch template metadata fields for EKS workers * test: e2e coverage for EKS worker IMDS hop limit and launch template metadata options * test: drop the unneeded GetCallerIdentity policy from the worker IMDS e2e * docs: describe the EKS worker IMDS defaults and launch template overrides * test: drop the stale GetCallerIdentity policy from the IRSA pod e2e |
||
|
|
f09250d2bb |
feat: count a node's vCPUs as online CPUs and reserve by host size (ADR-0015) (#1359)
A node counted physical cores, collapsing SMT threads, and held back a fixed 2 vCPU, so a 16-thread host offered 6 vCPU to instances. A vCPU is now one online CPU, as AWS counts it: a thread with SMT on, a core with SMT off or on ARM. The OS and Spinifex keep 1 CPU up to 8, 2 up to 16, 4 up to 63 and 8 from 64, and the rest is allocated one to one. The existing overrides stay operator-only. Invariant tests pin every tier boundary. |
||
|
|
8839407c71 |
feat(ui): console design system, side-panel resource views and live EC2 metrics (#1358)
* feat: lay the Spinifex UI design-system foundation Brand tokens in OKLCH with semantic status and a colour-blind-checked chart palette, Archivo headings and a 13px type scale, and a pre-paint theme script so dark mode never flashes white under the console CSP. Adds the missing Base UI primitives, a /design catalogue route, a route ratchet against hand-written tables, a ban on chart-library imports in routes, and lets the content column shrink so wide tables scroll in place. The dev server now forwards /api and /proxy to the Go console. Sonner is removed: its inline style element is blocked by the CSP. * feat(ui): side panels, TanStack table, uPlot charts and e2e gate - DataTable renders @tanstack/react-table, with column hiding as container queries so columns drop when a side panel narrows the list. - UniFi-style DetailPanel and ResourceView: Instances, VPCs and Internet gateways open in a panel beside the list from 1024px and as a full page below; selected, tab and create live in the URL. Create flows for instances, VPCs and gateways open in the same panel. - Instance monitoring charts on uPlot (CPU, network, packets), on simulated data and badged as such. - Dates in the AWS console form, e.g. 2026/06/04 02:00 GMT-5. - Tabs style Base UI's data-active, so the selected tab now shows. - Playwright suite gates CI as the UI End-to-End job in ui.yml. * feat(ui): one details component for panel and page, UniFi-style overlay panel The side panel now lies over the list at full height with a shaded edge, and a click on the list's background closes it. Instances, VPCs and internet gateways each render one details component as either the panel or the resource's own page, so the page gains the monitoring graphs and the panel gains IAM role, GPU, console output, change type and create image. SSH moves into Instance information as rows. Internet gateways attach and detach from the panel. * feat(ui): roll the panel pattern out to every service and gate screenshots in CI Every EC2, IAM, Route 53, Bedrock, EKS, ECS and RDS resource is now a list plus a side panel, with one details component serving as both the panel and the one-column page. DetailCard, DetailRow, ListCard, ResourceList and DeleteResourceButton are deleted. - Panel: slide-out close, row selection closes it, expand keeps the tab and fetched console output, PanelSpinner while loading. - Instances: info tips, theme-aware coloured console output, power button group plus Actions menu, Stop and Reboot confirms, security group, Elastic IP and network interface sections, and a live one-second monitoring window on simulated data. - Launch instance: OS tiles picking the newest version, architecture choice, location tile, expanded root volume, honest default subnet. - On/off settings are switches app-wide; disabled controls show cursor: not-allowed. - The e2e job runs in the pinned Playwright image with screenshots gating; make ui-baselines and make ui-e2e-container use the same image. * feat: bulk select and delete on every resource list, OS marks and instance type sizes Every list with a delete action gets row checkboxes and a selection bar. Delete confirms in a dialog naming each resource, makes one call per resource, keeps each refusal against its row and retries only failures. The Launch form shows distribution marks for Ubuntu, Debian, Rocky, Alpine and CentOS, served as files under the CSP, and states the selected instance type's vCPUs and memory. * feat: sign-in overlay, larger type scale, typed confirms on irreversible deletes and dialog shortcuts The sign-in card sits over an inert shell. Any sidebar group folds, and entering one unfolds it. Instance DNS names copy. Escape cancels and Cmd/Ctrl+Enter confirms every dialog. Volume, snapshot, RDS, EKS, ECS and hosted zone deletes need "delete" typed, and terminate needs "terminate". * feat: fade sign-in and sign-out in place, and show the confirm shortcut Signing in no longer reloads the page: the card and a lighter veil fade out and the console routes to the dashboard. Signing out cross-fades into the sign-in card with a Signed out notice. Confirm buttons show Cmd or Ctrl Enter for the platform. * feat(ui): generic sidebar group names and a paged S3 object browser The sidebar names its groups Compute, Databases, Authentication and Object Storage; the command palette still finds each by its AWS service name. Buckets get row selection and delete. Inside a bucket, folders and objects share one table paged by ListObjectsV2 continuation tokens, with a find box that queries by prefix, multi-select delete through DeleteObjects (folders with everything under them), and an object panel showing HeadObject properties, user metadata and a download. * feat(ui): show upload progress and stop the S3 proxy cutting off slow transfers The Upload button shows a running batch's percentage, and a large or slow batch opens a dialog with bytes sent, bit-rate, time left and per-file cancel and retry. Uploads run in a store outside React, so they continue while the user browses. The console's S3 proxy now allows an hour per request. The server's 15 s ReadTimeout cancelled every upload part that took longer, so large uploads failed on links below roughly 18 Mbit/s. * feat(ui): stream live EC2 metrics to the Monitoring tab The Monitoring tab drew simulated data. It now streams CPU, network bytes and packets from the owning node's qmp-collector every 500 ms while someone is watching, with nothing stored. - qmp-collector: a watched sampler on schedstat and tap counters, on a 30 s lease, keeping five minutes in memory for reconnects. It answers only watches for the account in the VM's discovery file. - awsgw: spinifex:GetInstanceMetrics, checked against the instance ARN, answered as text/event-stream in 60 s segments. Another account's instance is InvalidInstanceID.NotFound. - console: a signed stream reader that reconnects with Since and backs off on failure or an empty segment, stops on InvalidAction, and a chart axis that scrolls between samples. The simulator and its badge are removed. * feat: catch refused creates in every form, answer the third review, and guard tables Every create form now catches a refused mutation, so the failure shows beside the submit button and no longer escapes as an unhandled rejection. Three EKS tabs that swallowed a refused create now show it. Third-review answers: the attach dialog offers running or stopped instances in the volume's zone; the default security group's delete is disabled with its reason; the load balancer panel splits into Listeners and Attributes tabs; a main route table lists its implicit subnets; IAM single delete dialogs name the same dependants as the bulk ones; a snapshot can be deleted in any state. Every list in a route renders through DataTable, enforced by a unit test with a named allowance, and the /design baselines are redrawn in the pinned container. * feat: cap live metrics streams, prune hidden selections, and move panel focus Each gateway holds at most 10 live metrics streams per account and 200 in total, refusing past either with RequestLimitExceeded, and counts opened and refused streams. A row that leaves a list leaves its selection, the instances page uses the shared selection hook, the detail panel takes focus on open and returns it on close, and Escape yields only to the popup it was pressed in or a modal. The UI workflow also runs on live metrics backend changes. |
||
|
|
dee37b976a |
fix: keep an ECR token valid after its role session expires (#1357)
* test: authorise an ECR token from the live role once its session is gone * feat: carry the role ID in an ECR token minted for an assumed role * feat: rehydrate an assumed-role caller from the live role * fix: authorise an ECR token from its live role after the session expires * docs: note that an ECR token outlives its role session |
||
|
|
ce8272cf5e |
refactor: register EC2 through the ingress seam and delete the legacy service switch (#1355)
* test: characterise EC2 request labels and the cluster-unavailable gate order Pins the span, audit, throttle and policy-gate labels an EC2 request carries through the signed pipeline, and that the NATS gate answers before policy, action lookup and gateway-local actions. * refactor(gateway): register EC2 through the ADR-0002 seam EC2 is composed in awsgw from domains/ec2/awsapi and served by the registration seam. The legacy service switch and its tables are removed, along with the two paid-off gateway allowlist rows. * docs: record the EC2 seam registration in the package boundary migration * docs: record the EC2 seam registration PR number |
||
|
|
e4099f74b6 |
fix: make volume deletion asynchronous so a large volume cannot fail its own delete (#1356)
DeleteVolume returned only once every object behind the volume was gone, which made the call's latency a function of the volume's size. Object removal costs one round trip per object, so no timeout is both short enough for a control plane request and long enough for a large volume: on a 100 GiB volume the provider request overran its 30 s budget at 52 s, the tenant was told the delete failed, and the teardown that had already started was left with no record accountable for it. AWS does not work this way. DeleteVolume's output in the EC2 model is smithy.api#Unit, VolumeState includes deleting, and the documentation says a volume can remain in that state for several minutes. DeleteVolume now validates, decides every AWS-returnable error, records State=deleting and returns. VolumeReclaimReaper converges the teardown and removes the record only once it is complete, so an unreachable or saturated blob node delays reclamation instead of failing a delete the tenant has already been told succeeded. The reaper is cluster-wide and leader-gated, which is also what serialises the teardown: three concurrent destructive handlers ran one volume's objects on prod because a retry had nothing to collapse against. A volume already recorded as deleting answers a second delete from the record, which collapses both the tenant's retry and DeleteOnTermination's own delete. Two ordering fixes behind it. The provider handler now tears down local state before deleting objects, because the local half is fixed-cost and sat behind the half that scales, so a timeout left this node's WAL and dirty marker behind for good. And volume.delete and snapshot.delete are classified as data movement, since both reference real data and neither answers from state already held. |