Skip to content

fix: spawn quick-wins #103 #104 #108 #110 (truffle-backed validation) - #111

Merged
scttfrdmn merged 2 commits into
mainfrom
fix/quick-wins-103-104-106-108-110
Jun 12, 2026
Merged

fix: spawn quick-wins #103 #104 #108 #110 (truffle-backed validation)#111
scttfrdmn merged 2 commits into
mainfrom
fix/quick-wins-103-104-106-108-110

Conversation

@scttfrdmn

Copy link
Copy Markdown
Contributor

Batches four spawn bug-fixes. Each is self-contained; all unit/substrate-tested, make check green.

#103 — FSx cross-region S3 bucket 301

HeadBucket answers 301 PermanentRedirect/MovedPermanently (not NotFound) for a bucket that exists in another region. We were erroring on it. Now treat 301 as "exists, don't create" — catching both the smithy APIError code and a bare HTTP-301 ResponseError (the SDK surfaces it both ways). FSx itself still validates cross-region usability downstream.

#104 — MPI placement group on HPC instance types

hpc6a/hpc7a/hpc7g/… don't support cluster placement groups — they get low-latency networking from AWS HPC infrastructure. --auto-placement-group (on by default) now skips them gracefully with an info line; only an explicit --placement-group errors when unsupported. Support is read from truffle GetCapabilities, not a static allowlist.

#108 — RunInstances idempotency + classifiable errors

  • Optional LaunchConfig.ClientToken → set as RunInstances ClientToken (deterministic per cluster/entity/generation for cohort callers; empty = today's behavior, so no double-launch on a retried network timeout).
  • RunInstances failures wrapped in LaunchError{Code} carrying the verbatim AWS error code (InsufficientInstanceCapacity, RequestLimitExceeded, …) so callers classify capacity/quota/config faults on a code, not a string match. Unwrap preserved, so errors.As(&smithyAPIError) still works.

#110 — pre-flight instance-type constraints

Validate EFA / hibernation / MPI support before creating the IAM role or security group, with actionable errors (truffle find hints). One truffle GetCapabilities call backs all checks. HPC types are exempt from the placement-group requirement for --mpi (consistent with #104).


truffle integration: spawn now consumes truffle v0.38.1 as the instance-type capability authority instead of re-querying EC2 from spawn. One-way dependency (spawn→truffle), no cycle. Required bumping truffle's substrate dep to v0.70.0 (matching spawn) so the module graph resolves under go mod tidy — done in spore-host/truffle#49. isHPCInstanceType uses the hpc<digit> naming contract so new HPC families are covered without a hardcoded list.

Deferred (out of scope): #106 SageMaker (code parked in ~/src/fieldwork), #107 spored notifications, #109 q0 readiness tags, #101 --generalize warm AMI.

#103 FSx cross-region S3 bucket: HeadBucket answers 301/PermanentRedirect
  (not NotFound) for a bucket in another region. Treat that as "exists, don't
  create" instead of erroring. Catch both the smithy APIError code and a bare
  HTTP 301 ResponseError.

#104 MPI placement group on HPC types: hpc6a/hpc7a/hpc7g don't support cluster
  placement groups (they use AWS HPC networking). --auto-placement-group (default
  on) now SKIPs them gracefully; only an explicit --placement-group errors when
  unsupported. Capability comes from truffle GetCapabilities, not a static list.

#108 RunInstances idempotency + classifiable errors: add optional
  LaunchConfig.ClientToken (deterministic per cluster/entity/generation for
  cohort callers) and wrap RunInstances failures in LaunchError{Code} carrying
  the verbatim AWS error code, so callers classify capacity/quota/config faults
  on a code rather than string-matching. Empty token = today's behavior.

#110 pre-flight instance-type constraints: validate EFA / hibernation / MPI
  support BEFORE creating IAM role or security group, with actionable errors
  (truffle-find hints). One truffle GetCapabilities call backs all checks; HPC
  types are exempt from the placement-group requirement for --mpi.

spawn now consumes truffle (v0.38.1) as the instance-type capability authority
rather than re-querying EC2 itself — one-way dep, no cycle. isHPCInstanceType
uses the "hpc<digit>" naming contract so new HPC families are covered without a
hardcoded list.
@codecov

codecov Bot commented Jun 12, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 36.19048% with 67 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
cmd/launch.go 17.91% 55 Missing ⚠️
pkg/aws/client.go 57.14% 9 Missing ⚠️
pkg/aws/s3.go 82.35% 2 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

Extract the HeadBucket 301 detection into a pure isCrossRegionRedirect helper
and table-test both shapes (coded APIError + bare HTTP-301 ResponseError) plus
negatives. Add unit tests for newLaunchError code extraction / Unwrap chain.
Closes the patch-coverage gap on the quick-wins branch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant