Skip to content

Migration Guide

Guide for migrating between TinySystems versions.


Version Compatibility

TinySystemsKubernetesGoPlatform API
1.x1.20+1.21+v1alpha1

Migrating from v0.x to v1.x

Overview

Version 1.0 introduces several breaking changes to improve consistency and functionality:

  1. Component interface changes
  2. Port configuration updates
  3. Expression syntax improvements
  4. CR structure updates

Component Interface Changes

Instance() Method Required

Before (v0.x):

go
// Instance() was optional
type Component struct{}

After (v1.x):

go
// Instance() is required
func (c *Component) Instance() module.Component {
    return &Component{}
}

Migration: Add Instance() method to all components.

GetInfo() Returns ComponentInfo

Before (v0.x):

go
func (c *Component) GetInfo() (string, string, string) {
    return "name", "title", "description"
}

After (v1.x):

go
func (c *Component) GetInfo() module.ComponentInfo {
    return module.ComponentInfo{
        Name:        "name",
        Title:       "Title",
        Description: "Description",
        Category:    "Category",
        Tags:        []string{"tag1", "tag2"},
    }
}

Migration: Update GetInfo() to return ComponentInfo struct.

Handle() Context Parameter

Before (v0.x):

go
func (c *Component) Handle(output Handler, port string, msg any) error

After (v1.x):

go
func (c *Component) Handle(ctx context.Context, output Handler, port string, msg any) error

Migration: Add context.Context as first parameter.

Port Configuration

Position Constants

Before (v0.x):

go
Position: "left"
Position: "right"

After (v1.x):

go
Position: module.PositionLeft
Position: module.PositionRight

Migration: Replace string literals with module constants.

Source Field Clarification

The Source field meaning is unchanged but documentation is clearer:

  • Source: true = Port receives input (shown on left)
  • Source: false = Port sends output (shown on right)

System Port Constants

Before (v0.x):

go
port == "_settings"
port == "_control"

After (v1.x):

go
port == v1alpha1.SettingsPort
port == v1alpha1.ControlPort

Migration: Use constants from v1alpha1 package.

Expression Syntax

Root Reference

Before (v0.x):

yaml
# Both worked
value: "{{data.field}}"
value: "{{$.data.field}}"

After (v1.x):

yaml
# $ is required
value: "{{$.data.field}}"

Migration: Ensure all expressions use $ prefix.

Function Naming

Before (v0.x):

yaml
time: "{{rfc3339(now())}}"
text: "{{toUpper($.name)}}"

After (v1.x):

yaml
time: "{{RFC3339(now())}}"
text: "{{upper($.name)}}"

Migration: Update function names to new conventions.

CR Structure Changes

TinyNode Spec

Before (v0.x):

yaml
spec:
  module: my-module
  component: transformer
  config:
    - port: input
      data: ...

After (v1.x):

yaml
spec:
  component: my-module/transformer
  edges:
    - port: input
      data: ...

Migration:

  1. Combine module and component into component field
  2. Rename config to edges

TinyModule Registration

Before (v0.x):

yaml
spec:
  image: my-registry/my-module:v1
  components:
    - name: transformer

After (v1.x):

yaml
spec:
  image: my-registry/my-module:v1
  components:
    - name: transformer
      title: Transformer
      description: Transforms data
      category: Transform

Migration: Add title, description, and category to component entries.

ControlHandler Interface

Before (v0.x):

go
func (c *Component) HandleControl(state any, port string, msg any) (any, error)

After (v1.x):

go
func (c *Component) HandleControl(ctx context.Context, state any, port string, msg any) (any, error)

Migration: Add context.Context parameter.

Resource Manager

Before (v0.x):

go
c.client.CreateService(...)
c.client.CreateIngress(...)

After (v1.x):

go
c.resourceManager.ExposePort(ctx, resource.ExposePortRequest{
    Port:      8080,
    Hostnames: []string{"api.example.com"},
})

Migration: Use new ExposePort API instead of separate methods.


Migration Checklist

Component Code

  • [ ] Add Instance() method
  • [ ] Update GetInfo() to return ComponentInfo
  • [ ] Add context.Context to Handle() signature
  • [ ] Add context.Context to HandleControl() if implemented
  • [ ] Use v1alpha1 constants for system ports
  • [ ] Use module.Position* constants for port positions
  • [ ] Update resource manager calls

Helm Chart

  • [ ] Update CRD versions if included
  • [ ] Verify service account permissions
  • [ ] Update deployment templates

TinyNode Resources

  • [ ] Update spec.component format
  • [ ] Rename config to edges
  • [ ] Verify expression syntax

TinyModule Resources

  • [ ] Add component metadata (title, description, category)
  • [ ] Update API version

Automated Migration

CRD Migration Script

bash
#!/bin/bash
# Migrate TinyNode resources from v0.x to v1.x

kubectl get tinynodes -A -o yaml | \
  sed 's/config:/edges:/g' | \
  kubectl apply -f -

Code Migration

Use gofmt with custom rules or manual search/replace:

bash
# Find components needing Instance()
grep -r "func.*GetInfo.*module.ComponentInfo" --include="*.go" | \
  xargs -I {} dirname {} | \
  sort -u | \
  while read dir; do
    if ! grep -q "func.*Instance.*module.Component" "$dir"/*.go; then
      echo "Missing Instance(): $dir"
    fi
  done

Breaking Changes Summary

Areav0.xv1.x
Instance()OptionalRequired
GetInfo()Returns tupleReturns ComponentInfo
Handle()No contextHas context
HandleControl()No contextHas context
Port PositionStringConstant
System PortsStringConstant
Expression RootOptional $Required $
TinyNode configconfig:edges:
Component refSeparate fieldsCombined

Rollback Procedure

If migration causes issues:

  1. Helm rollback:

    bash
    helm rollback my-module
  2. CRD restore:

    bash
    kubectl apply -f backup/tinynodes.yaml
  3. Image rollback: Update Helm values to previous image tag


Getting Help

If you encounter migration issues:

  1. Check the FAQ
  2. Review error messages in controller logs
  3. Open a GitHub issue with:
    • Current version
    • Target version
    • Error messages
    • Component code (if applicable)

Build flow-based applications on Kubernetes