- Read the product version from version.json (jq) instead of a
date+sha build tag.
- Push each image as <service>-<version> and <service>-latest
(e.g. taylanbakircioglu/flowfish:backend-2.8.0 + backend-latest).
- New tag-release job (needs: build, contents: write): after all
images push, create and push an annotated git tag v<version>
(idempotent — skips if the tag already exists).
Bring the public mirror up to date with the latest developments:
- L7 HTTP Path Visibility & Per-Path Edge Model (v2.7.0): real HTTP
paths in the Service Map / Integration Hub / exports instead of "/".
Touches event_transformer (path extraction), graph-writer per-path
MERGE key + indexes, graph-query per-path counting, and the frontend.
- Beyla route decoration to fix the `/*/*/*/*/*` star-explosion in
API-gateway namespaces (low-cardinality route labelling).
- RabbitMQ queue-declaration resilience: graph-writer and
timeseries-writer tolerate a pre-existing queue whose arguments differ
from the declaration (bind to the existing queue instead of crashing).
- Version bump to 2.8.0 + CHANGELOG.
Example hostnames/annotations use placeholder values (example.com).
One matrix job intermittently failed at the login step with
'Get "https://registry-1.docker.io/v2/": context deadline exceeded'
while sibling jobs authenticated fine with the same secrets — a
transient network blip, not a credentials problem. Replace
docker/login-action with a `docker login --password-stdin` retry
loop (5 attempts, 10s backoff) so transient failures self-heal.
The frontend image was flagged on nginx 1.31.0 because the Dockerfiles
used the floating nginx:alpine (mainline) tag. No rewrite directives
exist in any nginx config, so the named-capture mitigation does not
apply; the remediation is the version update.
Pin every nginx reference to the patched 1.31.1-alpine release:
- frontend/Dockerfile, Dockerfile.production, Dockerfile.simple
- deployment/local-test/14-nginx-proxy.yaml (was nginx:alpine)
- deployment/local-test/l7-sample-apps.yaml (was nginx:1.25-alpine)
Validated with `nginx -t` on 1.31.1 for all configs.
The ToC had a single 'Kubernetes Deployment' entry pointing to an anchor
(#kubernetes-deployment) that does not exist in the document — the two real
headings are 'Kubernetes / K3s Quick Start (Recommended)' and 'Production
Kubernetes Deployment'. Split the entry into two correctly-anchored links so
clicking from the ToC actually navigates to the install steps.
All other ToC anchors and headings were cross-verified; no other broken
internal links were found.
README content
- Expand the eBPF data-collection section into L4 (Inspektor Gadget) and L7 (Beyla + flowfish-l7-collector) subsections
- Add three L7 deep-dive sections: Service Map, Distributed Tracing & Trace Explorer, APM Services & RED Metrics
- Add a "Why Flowfish?" highlights bullet list, a Production Readiness Checklist, and a Further Reading section
- Refresh System Architecture / Data Collection Flow ASCII diagrams to include the L7 path (Beyla -> flowfish-l7-collector -> l7-ingestion-service -> RabbitMQ flowfish.l7.*)
- Update API Reference, Data Architecture, Project Structure, and Backend Environment Variables to reflect the dual-agent (L4 + L7) setup
- Add troubleshooting entries for Beyla DaemonSet, L7 Service Map, and missing trace_id
- Simplify verbose detail throughout: collapse repeated phrasing, trim implementation-level file paths and code expressions, keep claims that are verified against the codebase
Discovery section reordering
- Place Service Map immediately after Dependency Map / Focus Mode so the maps are introduced back-to-back; move Network Explorer (tabular view) to the end of the section
Screenshots
- Refresh new-analysis-1.png with an L7-aware version (shows the L4 / L7 / Both Analysis Level selector and the updated sidebar with Service Map, Trace Explorer, and APM Services)
- Drop the redundant analysis-new-1.png: the new Entry Point screenshot already covers Basic Information in its current form, and the old shot is stuck in a pre-L7 state (L4-only tagline, pre-L7 sidebar)
- Add Settings UI for managing SDN pod CIDR ranges with backend API
- Propagate network config from Settings through orchestrator/gRPC to ingestion service
- Improve map drawer: correct Service node labels, simplify IP display
- Add aggregated workload drawer with pod details table, cluster badges
- Filter sdn-infrastructure noise entries in Integration Hub dependency summaries
- Maintain full backward compatibility with hardcoded CIDR defaults
Made-with: Cursor
Remove unnecessary EVENTS_BUFFER_LENGTH pipeline variable and
prepare-manifests.sh placeholder. The value is directly set in the
configmap template.
Made-with: Cursor
Production clusters need larger eBPF ring buffers to avoid lost events
during high-throughput analysis. Local-test keeps 8192 for smaller
environments.
Made-with: Cursor
The upgrade script now defaults to the current buffer value when it is
>= 8192, instead of always recommending 8192. Reducing buffer on busy
clusters causes eBPF ring buffer overflow and lost events. Also warns
if user manually enters a value below the minimum.
Made-with: Cursor
The upgrade script now updates the GADGET_IMAGE environment variable
alongside the container image (step 2/5). Also fixes the deployment
template to include version tag in GADGET_IMAGE value, ensuring
OCI gadget module pulls use the correct version.
Made-with: Cursor
Python f-string {{{{ produced {{ in bash output, but kubectl/oc jsonpath
requires single braces {.field}. This caused all cluster state queries
to return "unknown" and "0/0" pods during upgrade.
Made-with: Cursor
Adds subtle orange border, rounded corners and light background to the
version text when upgrade is available, making it visually distinct as
an interactive element while staying compact under the HEALTHY tag.
Made-with: Cursor
Version text turns orange with a small arrow icon when upgrade is available,
eliminating the visual asymmetry between HEALTHY badge and UPGRADE tag.
Made-with: Cursor
The update_analysis_limits endpoint had an inline case-sensitive role
check ('Admin'/'Super Admin') instead of using the existing
check_admin_role helper which is case-insensitive. Frontend Settings
page had the same issue, showing Read-Only Mode for users with
lowercase 'admin' role in their JWT token.
Made-with: Cursor
When an analysis is stopped and restarted, the previous run's
gadget_errors and has_gadget_warnings were persisted in output_config
and never cleared, causing a false "Some gadgets failed to start"
warning in the UI even when all gadgets started successfully.
Made-with: Cursor
Upgrade script now interactively prompts for namespace, target version,
registry, memory limit, and buffer length with validation at each step.
Also includes pending fixes: sync gRPC method, migration dollar-quoting,
and double-v prefix in gadget version display.
Made-with: Cursor
- Reduce Inspektor Gadget memory limit from 12Gi to 6Gi with buffer optimization (16384->8192)
- Add InspektorGadgetHighMemory (>3Gi) and CriticalMemory (>5Gi) Prometheus alerts
- Add configurable event ingestion rate limiting via Settings UI (ingestion_rate_limit_per_second)
- Update /analysis-limits/defaults endpoint to read from DB with Pydantic fallback
- Orchestrator fetches rate limit via isolated HTTP call (avoids cross-thread async issues)
- Ingestion service uses session-based rate limit with >0 comparison (fixes or-operator semantic bug)
- Add gadget_version (field 22) and max_events_per_second (field 23) to protobuf StartCollectionRequest
- Sync backend/proto with proto/ (add GadgetError message to backend copy)
- Upgrade Inspektor Gadget from v0.48.0 to v0.50.1 across all references
- Dynamic OCI image tagging: cluster-specific gadget_version flows through gRPC to ingestion service
- Fix get_cluster_sync SQL to include gadget_version column
- Fix NULL gadget_version causing protobuf TypeError (row[10] or '' pattern)
- Add GET /clusters/{id}/gadget-upgrade-script endpoint with cluster-specific parameters
- Add GadgetUpgradeModal and semver-based upgrade badge to Cluster Management page
- Add upgrade available indicator to Dashboard OperationsTab
- Include supported_gadget_version in GET /clusters response
- Update cluster_validator minimum supported version from v0.18 to v0.46.0
- Add ingestion_rate_limit_per_second to migration seed data and auto_stop_monitor fallback
- Improve AnalysisWizard Rolling Window and Recurring mode descriptions
- Add GADGET_SUPPORTED_VERSION and GADGET_MIN_SUPPORTED_VERSION to backend config
- Fix hardcoded "1.0.0" version in backend root/info endpoints to use __full_version__
- Replace grep -oP with POSIX grep -oE in upgrade script (macOS compatibility)
- Add ConfigMap events-buffer-length optimization step to upgrade script
- Add GADGET_VERSION sed substitution to prepare-manifests.sh
- Bump Flowfish version from 2.4.0 to 2.5.0
- Update pipeline GADGET_VERSION variable and all documentation references
Made-with: Cursor
CRA restricts imports from outside src/. Use build-time environment
variable instead: npm scripts read version.json and set REACT_APP_VERSION,
which CRA embeds into the bundle via DefinePlugin.
Dockerfiles updated to COPY version.json to / so the path resolves
correctly inside the container (/app/../version.json = /version.json).
Made-with: Cursor
- Redesign multi-service summary card with structured Statistic layout
and namespace tags instead of wrapping comma-separated text
- Add direct "Generate API Key" button linking to Settings > API Keys tab
- Add URL param support (?tab=) to Settings for deep-linking to specific tabs
- Fix admin warning incorrectly showing on API Keys tab (key mismatch: api-keys vs api-tokens)
Made-with: Cursor
Replace client-side event bucketing (limited to 50 paginated events) with
server-side ClickHouse aggregation using toStartOfInterval(). This fixes
the timeline showing a single bar despite multiple analysis runs.
Backend:
- Add query_event_histogram() to timeseries-query with epoch-aligned
bucket generation, capability_checks security filter, and count()-based
empty table detection
- Add GET /events/histogram endpoints through all layers (timeseries-query,
backend repository, service, router with analysis_id validation)
Frontend:
- Add getEventHistogram RTK Query hook with EventHistogram cache tag
- Replace client-side timelineData bucketing with server-side histogram
- Stacked bar colors (sorted by eventTypeConfig order for consistency)
- Clickable bars for time-range filtering (zoom-in)
- Loading skeleton, smart time labels (DD MMM HH:mm for multi-day),
full event type legend filtered by presence, total event count in header
- event_types filter synced with histogram query
Documentation:
- Update CURRENT_ARCHITECTURE, DATA_SOURCES, ARCHITECTURE_DETAILED,
services/README, and OpenAPI spec with /events/histogram endpoint
Made-with: Cursor
Kubernetes DNS search domain expansion creates multiple NXDOMAIN queries
for the same external domain (e.g. auth.docker.io.cluster.local,
auth.docker.io.svc.cluster.local). Without normalization, each variant
becomes a separate Neo4j node, inflating Public connections on the Map.
Backend (graph-writer):
- Rewrite _normalize_dns_name with TLD-safe 4-step algorithm
- Strip .svc.cluster.local, .<ns>.svc.cluster.local, .cluster.local
- Support custom search domains via DNS_SEARCH_DOMAINS env var
- Apply normalization in process_dns_query and process_sni_event
- Fix NXDOMAIN vertex overriding NOERROR resolved IP data
- Add KNOWN_TLDS/MULTI_LEVEL_TLDS for .com.tr/.co.uk safety checks
Frontend (NetworkExplorer):
- Add "Hide Search Domain Artifacts" toggle on DNS Queries tab
- Detect NXDOMAIN entries ending with .cluster.local
- Show artifact count, toggle hidden by default
Raw ClickHouse data and API responses are NOT modified — only the
dependency graph (Neo4j) is deduplicated. Full debugging data preserved.
Tests: 31 cases covering normalization, edge cases, and integration.
Made-with: Cursor
The config-generated emptyDir volume added inside an f-string
used literal {} which Python interprets as an empty expression.
Escaped to {{}} so it renders as {} in the generated script.
Made-with: Cursor
Apply init container auto-detection to kubernetes-manifests DaemonSet
and ConfigMap. Update OPENSHIFT_GADGET_FIX.md and README with
detect-runtime troubleshooting guidance.
Made-with: Cursor
Apply the same init container auto-detection to the setup script
generator (clusters.py). Both emptyDir and PVC DaemonSet variants
now detect K3s/RKE2/MicroK8s/standard containerd socket paths
automatically at pod startup.
Made-with: Cursor
Add init container to Inspektor Gadget DaemonSet that detects the correct
containerd socket path at pod startup. Supports K3s, RKE2, MicroK8s, and
standard Kubernetes without manual configuration. Also adds hostPID,
hostNetwork, and dnsPolicy for proper eBPF tracing.
Made-with: Cursor
Restructure /dependencies/summary response to provide per-service
downstream/callers breakdowns instead of a single aggregated view.
Backend:
- Unified loop in format_dependency_summary handles single and multi-service
identically, fixing replica data loss bug for single-service queries
- Each matched_service now carries its own downstream/callers DependencySummaryGroup
- New top-level summary object with globally deduplicated aggregate counts
(split downstream_critical_count and callers_critical_count)
- hop_count added to _compact_service (only when > 1 to avoid depth=1 noise)
- _dedup_entries now preserves entry with lowest hop_count on collision
- multi_service flag now correctly checks collapsed workload count
Frontend:
- Updated TypeScript interfaces (DependencySummary, MatchedService with groups)
- IntegrationHub Preview: per-service Collapse for multi-service, summary stats
- DependencyCategoryGroup: conditional hop_count column for multi-depth queries
- Snippet builders updated to parse matched_services and summary structure
API & Docs:
- OpenAPI spec: new DependencySummary schema, depth parameter descriptions
- README, feature-list, DATA_ARCHITECTURE docs updated
- Fixed pre-existing doc bug (default traversal depth 3 -> 1)
Made-with: Cursor