Crane is a Kubernetes migration tool that helps migrate workloads between clusters. It follows Unix philosophy: small, focused tools assembled in powerful ways.
Architecture:
- CLI tool written in Go
- Plugin-based transformation system
- Non-destructive pipeline: export → transform → apply
- Works with Kubernetes API, unstructured resources
Key repositories:
- migtools/crane (this repo) - CLI tool
- migtools/crane-lib - transformation logic
- migtools/crane-plugins - community plugins
- backube/pvc-transfer - PV migration
- Follow standard Go idioms and effective Go practices
- Use
gofmtfor formatting (already enforced) - Prefer explicit error messages with context
- When working with Kubernetes API objects:
- Use
*unstructured.Unstructuredfor dynamic resources - Always check type assertions and provide informative error messages
- Include the actual resource type and API resource name in errors
- Use
CRITICAL: Error messages must be actionable and include:
- The actual type received (not nil pointers to variables)
- The API resource being processed
- Enough context to debug without re-running
Example of good error handling:
// BAD - shows nil pointer
fmt.Errorf("expected *unstructured.Unstructured but got %T", u)
// GOOD - shows actual object type
fmt.Errorf("expected *unstructured.Unstructured but got %T", object)- All new features require tests
- Bug fixes should include regression tests when possible
- Use table-driven tests for multiple scenarios
- Test files:
*_test.goin same package - Run tests:
go test ./... - E2E tests live in
e2e-tests/
- Commands in
cmd/<command>/(apply, export, transform, etc.) - Each command is self-contained with its own package
- Shared utilities should go in crane-lib, not duplicated
- Plugin system for transformations (JSONPatch format)
- Check existing issues and PRs to avoid duplication
- For bugs: verify reproduction steps
- For features: ensure alignment with Crane's Unix philosophy
- Keep changes focused - one logical change per PR
- Bug fixes should be minimal, surgical changes
- Don't refactor unrelated code in the same PR
- Preserve backward compatibility unless explicitly breaking
- Use conventional commits format:
type: descriptionfix:for bug fixesfeat:for new featuresrefactor:for code restructuringtest:for test additionsdocs:for documentation
- Keep commits atomic and logical
- Include issue references when applicable
Title: Clear, concise (< 70 chars) Body must include:
Before submitting:
- Code compiles:
go build ./... - Tests pass:
go test ./... - Error messages are informative
- No unnecessary refactoring
- Backward compatible (or documented breaking change)
- Always validate type assertions
- Use
meta.Accessorfor metadata access when possible - Handle API errors gracefully (not found, forbidden, etc.)
- Resource names format:
Kind_group_version_namespace_name.yaml
- Respect namespace boundaries
- Handle cluster-scoped vs namespaced resources correctly
- Paginate large resource lists
- Log resource counts and progress
- JSONPatch operations only (RFC 6902)
- Transformations must be idempotent
- Document plugin behavior clearly
- Test transformations with real Kubernetes objects
- Don't assume object types - always check type assertions
- Don't use nil pointer variables in error messages - use the actual object
- Don't modify cluster state in export - read-only operations
- Don't hardcode API versions - use discovery
- Don't skip error context - include resource names and types
- Read the affected file first
- Understand the context and data flow
- Make minimal, targeted changes
- Test error paths explicitly
- Update error messages to be developer-friendly
- Check if similar functionality exists
- Consider plugin system for extensibility
- Follow existing patterns in cmd/ structure
- Document new flags and behavior
- Verify error messages are actionable
- Check for proper type assertions
- Ensure Kubernetes API best practices
- Look for potential nil pointer dereferences
Migration Philosophy:
- Non-destructive operations
- Transparent, auditable pipelines
- Output to disk for versioning
- Repeatable with same inputs
User Experience:
- Clear progress logging
- Helpful error messages
- Dry-run capabilities
- GitOps-friendly output