Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@ and the chart uses SemVer (`version`) plus the upstream Forail CalVer

## [Unreleased]

## [2026.7.1] - 2026-07-26

### Fixed
- **An upgrade no longer leaves the `default` queue unable to run anything.**
`register_queue` assigns instances only when it creates the group, so on an
upgrade it printed `Instance Group already registered default` and assigned
nothing — and an empty regular instance group accepts job launches and never
runs them. The init Job now asserts membership itself, alongside the
container-group flag it already asserted.

### Changed
- `images.backend.tag` pinned to `2026.07.1`, which carries the matching backend
fix: the task pod used to re-register itself as `control` and flip `default`
back to a ContainerGroup on every start, undoing what this Job sets. The
frontend stays at `2026.07.0` — it is unchanged.

## [2026.7.0] - 2026-07-25

### Added
- **Job-execution RBAC** (`templates/rbac.yaml`): a `forail` ServiceAccount plus
a namespaced `Role`/`RoleBinding` (`forail-job-runner`) granting
Expand Down
4 changes: 2 additions & 2 deletions Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v2
name: forail
description: Forail Platform — automation, RBAC, EDA, observability (k8s deployment)
type: application
version: 2026.7.0
appVersion: "2026.07.0"
version: 2026.7.1
appVersion: "2026.07.1"
# forail-operator lives in its own repo (forail-platform/forail-operator) and
# is installed separately via its own helm chart:
# helm install forail-operator <operator-chart-source> -n forail --set forail.token=<PAT>
Expand Down
67 changes: 36 additions & 31 deletions files/scripts/init.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,44 +30,49 @@ forail-manage provision_instance --skip-checks \
--hostname="${NODE_NAME}" \
--node_type="${NODE_TYPE}"

# provision_instance only inserts if missing — it does not update an
# already-registered instance. forail-web auto-registers itself as
# 'control' on first startup before this Job runs, so without this
# explicit ORM update the cluster ends up with node_type=control and
# refuses to execute jobs (it can only orchestrate). Force-set the
# requested type so launches stay on this instance via the local
# Receptor work command instead of routing to a ContainerGroup.
forail-manage shell -c "
from forail.main.models import Instance
i = Instance.objects.filter(hostname='${NODE_NAME}').first()
if i and i.node_type != '${NODE_TYPE}':
i.node_type = '${NODE_TYPE}'
i.save(update_fields=['node_type'])
print('Updated', i.hostname, 'node_type ->', i.node_type)
else:
print('Instance node_type already', i.node_type if i else 'missing')
"

echo "==> Registering queues..."
forail-manage register_queue --skip-checks --queuename=controlplane --instance_percent=100
forail-manage register_queue --skip-checks --queuename=default --instance_percent=100

# A post_migrate signal in forail auto-creates the 'default' InstanceGroup
# as is_container_group=true when running in k8s. Without a working
# ContainerGroup that resolves to a local Receptor work type, every job
# launch errors with 'unknown work type kubernetes-incluster-auth'.
# Flip it back to a regular IG so register_queue's instance assignment
# above is honored and jobs run via the local work command.
# Three things the 'default' group needs that the commands above do not
# reliably leave behind:
#
# 1. is_container_group=false. A post_migrate signal auto-creates 'default' as
# a ContainerGroup on k8s, and without a work type that resolves locally
# every launch errors with 'unknown work type kubernetes-incluster-auth'.
# 2. Membership. On an UPGRADE the group already exists, so register_queue
# prints "Instance Group already registered" and assigns no instance. The
# group is left empty and every job sits in "pending" forever, with nothing
# in the UI or the logs to say why.
# 3. node_type, as a backstop. The real fix for that one is in the backend —
# the task pod re-runs provision_instance on every start and used to
# re-register as 'control' unconditionally, undoing whatever this Job set;
# it now honours FORAIL_NODE_TYPE. Keep the assertion so a newer chart
# paired with an older backend image still converges.
forail-manage shell -c "
from forail.main.models import InstanceGroup
from forail.main.models import Instance, InstanceGroup
ig = InstanceGroup.objects.filter(name='default').first()
if ig and ig.is_container_group:
ig.is_container_group = False
ig.pod_spec_override = ''
ig.save(update_fields=['is_container_group', 'pod_spec_override'])
print('default IG: is_container_group -> False')
if not ig:
print('default IG missing — register_queue did not create it')
else:
print('default IG already non-container or missing')
if ig.is_container_group:
ig.is_container_group = False
ig.pod_spec_override = ''
ig.save(update_fields=['is_container_group', 'pod_spec_override'])
print('default IG: is_container_group -> False')
i = Instance.objects.filter(hostname='${NODE_NAME}').first()
if not i:
print('instance ${NODE_NAME} missing — cannot assign to default IG')
else:
if i.node_type != '${NODE_TYPE}':
i.node_type = '${NODE_TYPE}'
i.save(update_fields=['node_type'])
print('instance node_type ->', i.node_type)
if not ig.instances.filter(pk=i.pk).exists():
ig.instances.add(i)
print('default IG: added', i.hostname)
else:
print('default IG already contains', i.hostname)
"

echo "==> Creating preload data..."
Expand Down
2 changes: 1 addition & 1 deletion values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace:
images:
backend:
repository: ghcr.io/forail-platform/forail-backend
tag: "2026.07.0"
tag: "2026.07.1"
pullPolicy: IfNotPresent
frontend:
repository: ghcr.io/forail-platform/forail-frontend
Expand Down
Loading