diff --git a/CHANGELOG.md b/CHANGELOG.md index 4932ead..4df9978 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ## [Unreleased] +## [0.8.8] - 2026-10-06 + +### Fixed + +- A ControllerRevision opens in the details pane. Its data is a snapshot, so each value is shown as text. A ConfigMap or Secret whose values are strings stays as it is. + +### Changed + +- The screenshot tour saves every visible detail tab: YAML, events, related pods, logs, and terminal. Chat is left out. Data, Helm values, secret and ConfigMap YAML, Dapr component YAML, and Helm manifests are blurred in the PNG. A details load that fails during the tour no longer closes the app. +- AppStream screenshots stay on tag `v0.8.6`, where those images are stored. The `0.8.8` release entry points at this version's changelog. + ## [0.8.7] - 2026-10-05 ### Added diff --git a/WHATSNEW.md b/WHATSNEW.md index bfbbb6d..13965de 100644 --- a/WHATSNEW.md +++ b/WHATSNEW.md @@ -2,6 +2,10 @@ Short notes shown in the app after an upgrade. The full history, including maintainer notes, is [CHANGELOG.md](CHANGELOG.md). +## [0.8.8] - 2026-10-06 + +- A ControllerRevision opens in the details pane. Its data values are shown as text. + ## [0.8.7] - 2026-10-05 - When AI is on, Chat sits on the cluster overview. Analyze issues explains the current warnings and errors. diff --git a/assets/screenshots/apiservices-events.png b/assets/screenshots/apiservices-events.png new file mode 100644 index 0000000..ad2655a Binary files /dev/null and b/assets/screenshots/apiservices-events.png differ diff --git a/assets/screenshots/apiservices-yaml.png b/assets/screenshots/apiservices-yaml.png new file mode 100644 index 0000000..a45e5c2 Binary files /dev/null and b/assets/screenshots/apiservices-yaml.png differ diff --git a/assets/screenshots/applications-events.png b/assets/screenshots/applications-events.png new file mode 100644 index 0000000..7861ceb Binary files /dev/null and b/assets/screenshots/applications-events.png differ diff --git a/assets/screenshots/applications-logs.png b/assets/screenshots/applications-logs.png new file mode 100644 index 0000000..9fb69e4 Binary files /dev/null and b/assets/screenshots/applications-logs.png differ diff --git a/assets/screenshots/applications-pods.png b/assets/screenshots/applications-pods.png new file mode 100644 index 0000000..aaffaff Binary files /dev/null and b/assets/screenshots/applications-pods.png differ diff --git a/assets/screenshots/applications-terminal.png b/assets/screenshots/applications-terminal.png new file mode 100644 index 0000000..2d73fbe Binary files /dev/null and b/assets/screenshots/applications-terminal.png differ diff --git a/assets/screenshots/applications-yaml.png b/assets/screenshots/applications-yaml.png new file mode 100644 index 0000000..a1175e0 Binary files /dev/null and b/assets/screenshots/applications-yaml.png differ diff --git a/assets/screenshots/clusterrolebindings-events.png b/assets/screenshots/clusterrolebindings-events.png new file mode 100644 index 0000000..824275b Binary files /dev/null and b/assets/screenshots/clusterrolebindings-events.png differ diff --git a/assets/screenshots/clusterrolebindings-yaml.png b/assets/screenshots/clusterrolebindings-yaml.png new file mode 100644 index 0000000..713466c Binary files /dev/null and b/assets/screenshots/clusterrolebindings-yaml.png differ diff --git a/assets/screenshots/clusterroles-events.png b/assets/screenshots/clusterroles-events.png new file mode 100644 index 0000000..c360cb3 Binary files /dev/null and b/assets/screenshots/clusterroles-events.png differ diff --git a/assets/screenshots/clusterroles-yaml.png b/assets/screenshots/clusterroles-yaml.png new file mode 100644 index 0000000..4f6f550 Binary files /dev/null and b/assets/screenshots/clusterroles-yaml.png differ diff --git a/assets/screenshots/cnpg-clusters-events.png b/assets/screenshots/cnpg-clusters-events.png new file mode 100644 index 0000000..47e2ebc Binary files /dev/null and b/assets/screenshots/cnpg-clusters-events.png differ diff --git a/assets/screenshots/cnpg-clusters-yaml.png b/assets/screenshots/cnpg-clusters-yaml.png new file mode 100644 index 0000000..0442d49 Binary files /dev/null and b/assets/screenshots/cnpg-clusters-yaml.png differ diff --git a/assets/screenshots/cnpg-clusters.png b/assets/screenshots/cnpg-clusters.png new file mode 100644 index 0000000..2e628d1 Binary files /dev/null and b/assets/screenshots/cnpg-clusters.png differ diff --git a/assets/screenshots/components-events.png b/assets/screenshots/components-events.png new file mode 100644 index 0000000..4f42d34 Binary files /dev/null and b/assets/screenshots/components-events.png differ diff --git a/assets/screenshots/components-yaml.png b/assets/screenshots/components-yaml.png new file mode 100644 index 0000000..bd8afab Binary files /dev/null and b/assets/screenshots/components-yaml.png differ diff --git a/assets/screenshots/components.png b/assets/screenshots/components.png new file mode 100644 index 0000000..77d06cf Binary files /dev/null and b/assets/screenshots/components.png differ diff --git a/assets/screenshots/configmaps-events.png b/assets/screenshots/configmaps-events.png new file mode 100644 index 0000000..a223081 Binary files /dev/null and b/assets/screenshots/configmaps-events.png differ diff --git a/assets/screenshots/configmaps-yaml.png b/assets/screenshots/configmaps-yaml.png new file mode 100644 index 0000000..dbf89c3 Binary files /dev/null and b/assets/screenshots/configmaps-yaml.png differ diff --git a/assets/screenshots/configurations-events.png b/assets/screenshots/configurations-events.png new file mode 100644 index 0000000..e11aa9d Binary files /dev/null and b/assets/screenshots/configurations-events.png differ diff --git a/assets/screenshots/configurations-yaml.png b/assets/screenshots/configurations-yaml.png new file mode 100644 index 0000000..7450f4d Binary files /dev/null and b/assets/screenshots/configurations-yaml.png differ diff --git a/assets/screenshots/controllerrevisions-events.png b/assets/screenshots/controllerrevisions-events.png new file mode 100644 index 0000000..489ab3d Binary files /dev/null and b/assets/screenshots/controllerrevisions-events.png differ diff --git a/assets/screenshots/controllerrevisions-yaml.png b/assets/screenshots/controllerrevisions-yaml.png new file mode 100644 index 0000000..5b41642 Binary files /dev/null and b/assets/screenshots/controllerrevisions-yaml.png differ diff --git a/assets/screenshots/controllerrevisions.png b/assets/screenshots/controllerrevisions.png new file mode 100644 index 0000000..ed7a360 Binary files /dev/null and b/assets/screenshots/controllerrevisions.png differ diff --git a/assets/screenshots/csidrivers-events.png b/assets/screenshots/csidrivers-events.png new file mode 100644 index 0000000..bb9f8a7 Binary files /dev/null and b/assets/screenshots/csidrivers-events.png differ diff --git a/assets/screenshots/csidrivers-yaml.png b/assets/screenshots/csidrivers-yaml.png new file mode 100644 index 0000000..b38e2dc Binary files /dev/null and b/assets/screenshots/csidrivers-yaml.png differ diff --git a/assets/screenshots/csinodes-events.png b/assets/screenshots/csinodes-events.png new file mode 100644 index 0000000..5b2c92b Binary files /dev/null and b/assets/screenshots/csinodes-events.png differ diff --git a/assets/screenshots/csinodes-yaml.png b/assets/screenshots/csinodes-yaml.png new file mode 100644 index 0000000..02ac3a6 Binary files /dev/null and b/assets/screenshots/csinodes-yaml.png differ diff --git a/assets/screenshots/customresourcedefinitions-events.png b/assets/screenshots/customresourcedefinitions-events.png new file mode 100644 index 0000000..d779a11 Binary files /dev/null and b/assets/screenshots/customresourcedefinitions-events.png differ diff --git a/assets/screenshots/customresourcedefinitions-yaml.png b/assets/screenshots/customresourcedefinitions-yaml.png new file mode 100644 index 0000000..7734f7f Binary files /dev/null and b/assets/screenshots/customresourcedefinitions-yaml.png differ diff --git a/assets/screenshots/daemonsets-events.png b/assets/screenshots/daemonsets-events.png new file mode 100644 index 0000000..484f4e5 Binary files /dev/null and b/assets/screenshots/daemonsets-events.png differ diff --git a/assets/screenshots/daemonsets-logs.png b/assets/screenshots/daemonsets-logs.png new file mode 100644 index 0000000..af3ac69 Binary files /dev/null and b/assets/screenshots/daemonsets-logs.png differ diff --git a/assets/screenshots/daemonsets-pods.png b/assets/screenshots/daemonsets-pods.png new file mode 100644 index 0000000..11400b3 Binary files /dev/null and b/assets/screenshots/daemonsets-pods.png differ diff --git a/assets/screenshots/daemonsets-terminal.png b/assets/screenshots/daemonsets-terminal.png new file mode 100644 index 0000000..832c4ab Binary files /dev/null and b/assets/screenshots/daemonsets-terminal.png differ diff --git a/assets/screenshots/daemonsets-yaml.png b/assets/screenshots/daemonsets-yaml.png new file mode 100644 index 0000000..46aae51 Binary files /dev/null and b/assets/screenshots/daemonsets-yaml.png differ diff --git a/assets/screenshots/dapr-control-plane-events.png b/assets/screenshots/dapr-control-plane-events.png new file mode 100644 index 0000000..07188f2 Binary files /dev/null and b/assets/screenshots/dapr-control-plane-events.png differ diff --git a/assets/screenshots/dapr-control-plane-logs.png b/assets/screenshots/dapr-control-plane-logs.png new file mode 100644 index 0000000..18c7b53 Binary files /dev/null and b/assets/screenshots/dapr-control-plane-logs.png differ diff --git a/assets/screenshots/dapr-control-plane-terminal.png b/assets/screenshots/dapr-control-plane-terminal.png new file mode 100644 index 0000000..4fb421d Binary files /dev/null and b/assets/screenshots/dapr-control-plane-terminal.png differ diff --git a/assets/screenshots/dapr-control-plane-yaml.png b/assets/screenshots/dapr-control-plane-yaml.png new file mode 100644 index 0000000..379cd0c Binary files /dev/null and b/assets/screenshots/dapr-control-plane-yaml.png differ diff --git a/assets/screenshots/dapr-sidecars-events.png b/assets/screenshots/dapr-sidecars-events.png new file mode 100644 index 0000000..3e999ba Binary files /dev/null and b/assets/screenshots/dapr-sidecars-events.png differ diff --git a/assets/screenshots/dapr-sidecars-logs.png b/assets/screenshots/dapr-sidecars-logs.png new file mode 100644 index 0000000..087bfa3 Binary files /dev/null and b/assets/screenshots/dapr-sidecars-logs.png differ diff --git a/assets/screenshots/dapr-sidecars-terminal.png b/assets/screenshots/dapr-sidecars-terminal.png new file mode 100644 index 0000000..54b083a Binary files /dev/null and b/assets/screenshots/dapr-sidecars-terminal.png differ diff --git a/assets/screenshots/dapr-sidecars-yaml.png b/assets/screenshots/dapr-sidecars-yaml.png new file mode 100644 index 0000000..940efab Binary files /dev/null and b/assets/screenshots/dapr-sidecars-yaml.png differ diff --git a/assets/screenshots/deployments-events.png b/assets/screenshots/deployments-events.png new file mode 100644 index 0000000..58f493d Binary files /dev/null and b/assets/screenshots/deployments-events.png differ diff --git a/assets/screenshots/deployments-logs.png b/assets/screenshots/deployments-logs.png new file mode 100644 index 0000000..25746db Binary files /dev/null and b/assets/screenshots/deployments-logs.png differ diff --git a/assets/screenshots/deployments-pods.png b/assets/screenshots/deployments-pods.png new file mode 100644 index 0000000..d3cb24f Binary files /dev/null and b/assets/screenshots/deployments-pods.png differ diff --git a/assets/screenshots/deployments-terminal.png b/assets/screenshots/deployments-terminal.png new file mode 100644 index 0000000..9f2a648 Binary files /dev/null and b/assets/screenshots/deployments-terminal.png differ diff --git a/assets/screenshots/deployments-yaml.png b/assets/screenshots/deployments-yaml.png new file mode 100644 index 0000000..e997c34 Binary files /dev/null and b/assets/screenshots/deployments-yaml.png differ diff --git a/assets/screenshots/endpoints-events.png b/assets/screenshots/endpoints-events.png new file mode 100644 index 0000000..68e1a14 Binary files /dev/null and b/assets/screenshots/endpoints-events.png differ diff --git a/assets/screenshots/endpoints-yaml.png b/assets/screenshots/endpoints-yaml.png new file mode 100644 index 0000000..aaf2528 Binary files /dev/null and b/assets/screenshots/endpoints-yaml.png differ diff --git a/assets/screenshots/endpointslices-events.png b/assets/screenshots/endpointslices-events.png new file mode 100644 index 0000000..9f40ec7 Binary files /dev/null and b/assets/screenshots/endpointslices-events.png differ diff --git a/assets/screenshots/endpointslices-yaml.png b/assets/screenshots/endpointslices-yaml.png new file mode 100644 index 0000000..5d3df18 Binary files /dev/null and b/assets/screenshots/endpointslices-yaml.png differ diff --git a/assets/screenshots/flowschemas-events.png b/assets/screenshots/flowschemas-events.png new file mode 100644 index 0000000..c5d2b24 Binary files /dev/null and b/assets/screenshots/flowschemas-events.png differ diff --git a/assets/screenshots/flowschemas-yaml.png b/assets/screenshots/flowschemas-yaml.png new file mode 100644 index 0000000..964aa74 Binary files /dev/null and b/assets/screenshots/flowschemas-yaml.png differ diff --git a/assets/screenshots/helm-charts-yaml.png b/assets/screenshots/helm-charts-yaml.png new file mode 100644 index 0000000..ea7abd4 Binary files /dev/null and b/assets/screenshots/helm-charts-yaml.png differ diff --git a/assets/screenshots/helm-releases-history.png b/assets/screenshots/helm-releases-history.png new file mode 100644 index 0000000..8d3c543 Binary files /dev/null and b/assets/screenshots/helm-releases-history.png differ diff --git a/assets/screenshots/helm-releases-manifest.png b/assets/screenshots/helm-releases-manifest.png new file mode 100644 index 0000000..c0739ef Binary files /dev/null and b/assets/screenshots/helm-releases-manifest.png differ diff --git a/assets/screenshots/helm-releases-values.png b/assets/screenshots/helm-releases-values.png new file mode 100644 index 0000000..b126b3f Binary files /dev/null and b/assets/screenshots/helm-releases-values.png differ diff --git a/assets/screenshots/helm-releases-yaml.png b/assets/screenshots/helm-releases-yaml.png new file mode 100644 index 0000000..d4a1be4 Binary files /dev/null and b/assets/screenshots/helm-releases-yaml.png differ diff --git a/assets/screenshots/helm-releases.png b/assets/screenshots/helm-releases.png new file mode 100644 index 0000000..0c4d981 Binary files /dev/null and b/assets/screenshots/helm-releases.png differ diff --git a/assets/screenshots/ipaddresses-events.png b/assets/screenshots/ipaddresses-events.png new file mode 100644 index 0000000..55c3376 Binary files /dev/null and b/assets/screenshots/ipaddresses-events.png differ diff --git a/assets/screenshots/ipaddresses-yaml.png b/assets/screenshots/ipaddresses-yaml.png new file mode 100644 index 0000000..720810e Binary files /dev/null and b/assets/screenshots/ipaddresses-yaml.png differ diff --git a/assets/screenshots/leases-events.png b/assets/screenshots/leases-events.png new file mode 100644 index 0000000..b7bf404 Binary files /dev/null and b/assets/screenshots/leases-events.png differ diff --git a/assets/screenshots/leases-yaml.png b/assets/screenshots/leases-yaml.png new file mode 100644 index 0000000..65d8650 Binary files /dev/null and b/assets/screenshots/leases-yaml.png differ diff --git a/assets/screenshots/longhorn-nodes-events.png b/assets/screenshots/longhorn-nodes-events.png new file mode 100644 index 0000000..a997bb2 Binary files /dev/null and b/assets/screenshots/longhorn-nodes-events.png differ diff --git a/assets/screenshots/longhorn-nodes-yaml.png b/assets/screenshots/longhorn-nodes-yaml.png new file mode 100644 index 0000000..82abd3e Binary files /dev/null and b/assets/screenshots/longhorn-nodes-yaml.png differ diff --git a/assets/screenshots/longhorn-volumes-events.png b/assets/screenshots/longhorn-volumes-events.png new file mode 100644 index 0000000..27ea2bc Binary files /dev/null and b/assets/screenshots/longhorn-volumes-events.png differ diff --git a/assets/screenshots/longhorn-volumes-yaml.png b/assets/screenshots/longhorn-volumes-yaml.png new file mode 100644 index 0000000..af19bd4 Binary files /dev/null and b/assets/screenshots/longhorn-volumes-yaml.png differ diff --git a/assets/screenshots/manifest.json b/assets/screenshots/manifest.json index c6a95bf..e98da86 100644 --- a/assets/screenshots/manifest.json +++ b/assets/screenshots/manifest.json @@ -22,38 +22,142 @@ "Id": "apiservices", "Window": "apiservices.png" }, + { + "Id": "apiservices-yaml", + "Window": "apiservices-yaml.png" + }, + { + "Id": "apiservices-events", + "Window": "apiservices-events.png" + }, { "Id": "flowschemas", "Window": "flowschemas.png" }, + { + "Id": "flowschemas-yaml", + "Window": "flowschemas-yaml.png" + }, + { + "Id": "flowschemas-events", + "Window": "flowschemas-events.png" + }, { "Id": "prioritylevelconfigurations", "Window": "prioritylevelconfigurations.png" }, + { + "Id": "prioritylevelconfigurations-yaml", + "Window": "prioritylevelconfigurations-yaml.png" + }, + { + "Id": "prioritylevelconfigurations-events", + "Window": "prioritylevelconfigurations-events.png" + }, { "Id": "nodes", "Window": "nodes.png" }, + { + "Id": "nodes-yaml", + "Window": "nodes-yaml.png" + }, { "Id": "nodes-images", "Window": "nodes-images.png" }, + { + "Id": "nodes-events", + "Window": "nodes-events.png" + }, { "Id": "applications", "Window": "applications.png" }, + { + "Id": "applications-yaml", + "Window": "applications-yaml.png" + }, + { + "Id": "applications-events", + "Window": "applications-events.png" + }, + { + "Id": "applications-pods", + "Window": "applications-pods.png" + }, + { + "Id": "applications-logs", + "Window": "applications-logs.png" + }, + { + "Id": "applications-terminal", + "Window": "applications-terminal.png" + }, { "Id": "workloads-overview", "Window": "workloads-overview.png" }, + { + "Id": "controllerrevisions", + "Window": "controllerrevisions.png" + }, + { + "Id": "controllerrevisions-yaml", + "Window": "controllerrevisions-yaml.png" + }, + { + "Id": "controllerrevisions-events", + "Window": "controllerrevisions-events.png" + }, { "Id": "daemonsets", "Window": "daemonsets.png" }, + { + "Id": "daemonsets-yaml", + "Window": "daemonsets-yaml.png" + }, + { + "Id": "daemonsets-events", + "Window": "daemonsets-events.png" + }, + { + "Id": "daemonsets-pods", + "Window": "daemonsets-pods.png" + }, + { + "Id": "daemonsets-logs", + "Window": "daemonsets-logs.png" + }, + { + "Id": "daemonsets-terminal", + "Window": "daemonsets-terminal.png" + }, { "Id": "deployments", "Window": "deployments.png" }, + { + "Id": "deployments-yaml", + "Window": "deployments-yaml.png" + }, + { + "Id": "deployments-events", + "Window": "deployments-events.png" + }, + { + "Id": "deployments-pods", + "Window": "deployments-pods.png" + }, + { + "Id": "deployments-logs", + "Window": "deployments-logs.png" + }, + { + "Id": "deployments-terminal", + "Window": "deployments-terminal.png" + }, { "Id": "pods", "Window": "pods.png" @@ -62,165 +166,521 @@ "Id": "pods-yaml", "Window": "pods-yaml.png" }, + { + "Id": "pods-events", + "Window": "pods-events.png" + }, { "Id": "pods-logs", "Window": "pods-logs.png" }, { - "Id": "pods-chat", - "Window": "pods-chat.png" + "Id": "pods-terminal", + "Window": "pods-terminal.png" }, { "Id": "replicasets", "Window": "replicasets.png" }, + { + "Id": "replicasets-yaml", + "Window": "replicasets-yaml.png" + }, + { + "Id": "replicasets-events", + "Window": "replicasets-events.png" + }, + { + "Id": "replicasets-pods", + "Window": "replicasets-pods.png" + }, + { + "Id": "replicasets-logs", + "Window": "replicasets-logs.png" + }, + { + "Id": "replicasets-terminal", + "Window": "replicasets-terminal.png" + }, { "Id": "statefulsets", "Window": "statefulsets.png" }, + { + "Id": "statefulsets-yaml", + "Window": "statefulsets-yaml.png" + }, + { + "Id": "statefulsets-events", + "Window": "statefulsets-events.png" + }, + { + "Id": "statefulsets-pods", + "Window": "statefulsets-pods.png" + }, + { + "Id": "statefulsets-logs", + "Window": "statefulsets-logs.png" + }, + { + "Id": "statefulsets-terminal", + "Window": "statefulsets-terminal.png" + }, { "Id": "configmaps", "Window": "configmaps.png" }, + { + "Id": "configmaps-yaml", + "Window": "configmaps-yaml.png" + }, { "Id": "configmaps-data", "Window": "configmaps-data.png" }, + { + "Id": "configmaps-events", + "Window": "configmaps-events.png" + }, { "Id": "leases", "Window": "leases.png" }, + { + "Id": "leases-yaml", + "Window": "leases-yaml.png" + }, + { + "Id": "leases-events", + "Window": "leases-events.png" + }, { "Id": "mutatingwebhookconfigurations", "Window": "mutatingwebhookconfigurations.png" }, + { + "Id": "mutatingwebhookconfigurations-yaml", + "Window": "mutatingwebhookconfigurations-yaml.png" + }, + { + "Id": "mutatingwebhookconfigurations-events", + "Window": "mutatingwebhookconfigurations-events.png" + }, { "Id": "poddisruptionbudgets", "Window": "poddisruptionbudgets.png" }, + { + "Id": "poddisruptionbudgets-yaml", + "Window": "poddisruptionbudgets-yaml.png" + }, + { + "Id": "poddisruptionbudgets-events", + "Window": "poddisruptionbudgets-events.png" + }, { "Id": "priorityclasses", "Window": "priorityclasses.png" }, + { + "Id": "priorityclasses-yaml", + "Window": "priorityclasses-yaml.png" + }, + { + "Id": "priorityclasses-events", + "Window": "priorityclasses-events.png" + }, { "Id": "runtimeclasses", "Window": "runtimeclasses.png" }, + { + "Id": "runtimeclasses-yaml", + "Window": "runtimeclasses-yaml.png" + }, + { + "Id": "runtimeclasses-events", + "Window": "runtimeclasses-events.png" + }, { "Id": "secrets", "Window": "secrets.png" }, + { + "Id": "secrets-yaml", + "Window": "secrets-yaml.png" + }, + { + "Id": "secrets-data", + "Window": "secrets-data.png" + }, + { + "Id": "secrets-events", + "Window": "secrets-events.png" + }, { "Id": "validatingwebhookconfigurations", "Window": "validatingwebhookconfigurations.png" }, + { + "Id": "validatingwebhookconfigurations-yaml", + "Window": "validatingwebhookconfigurations-yaml.png" + }, + { + "Id": "validatingwebhookconfigurations-events", + "Window": "validatingwebhookconfigurations-events.png" + }, { "Id": "port-forwarding", "Window": "port-forwarding.png" }, + { + "Id": "port-forwarding-yaml", + "Window": "port-forwarding-yaml.png" + }, { "Id": "endpointslices", "Window": "endpointslices.png" }, + { + "Id": "endpointslices-yaml", + "Window": "endpointslices-yaml.png" + }, + { + "Id": "endpointslices-events", + "Window": "endpointslices-events.png" + }, { "Id": "endpoints", "Window": "endpoints.png" }, + { + "Id": "endpoints-yaml", + "Window": "endpoints-yaml.png" + }, + { + "Id": "endpoints-events", + "Window": "endpoints-events.png" + }, { "Id": "ipaddresses", "Window": "ipaddresses.png" }, + { + "Id": "ipaddresses-yaml", + "Window": "ipaddresses-yaml.png" + }, + { + "Id": "ipaddresses-events", + "Window": "ipaddresses-events.png" + }, { "Id": "servicecidrs", "Window": "servicecidrs.png" }, + { + "Id": "servicecidrs-yaml", + "Window": "servicecidrs-yaml.png" + }, + { + "Id": "servicecidrs-events", + "Window": "servicecidrs-events.png" + }, { "Id": "services", "Window": "services.png" }, { - "Id": "csidrivers", - "Window": "csidrivers.png" + "Id": "services-yaml", + "Window": "services-yaml.png" + }, + { + "Id": "services-events", + "Window": "services-events.png" + }, + { + "Id": "services-pods", + "Window": "services-pods.png" }, { "Id": "csinodes", "Window": "csinodes.png" }, + { + "Id": "csinodes-yaml", + "Window": "csinodes-yaml.png" + }, + { + "Id": "csinodes-events", + "Window": "csinodes-events.png" + }, { "Id": "persistentvolumeclaims", "Window": "persistentvolumeclaims.png" }, + { + "Id": "persistentvolumeclaims-yaml", + "Window": "persistentvolumeclaims-yaml.png" + }, + { + "Id": "persistentvolumeclaims-events", + "Window": "persistentvolumeclaims-events.png" + }, + { + "Id": "volume-files", + "Window": "volume-files.png" + }, { "Id": "persistentvolumes", "Window": "persistentvolumes.png" }, + { + "Id": "persistentvolumes-yaml", + "Window": "persistentvolumes-yaml.png" + }, + { + "Id": "persistentvolumes-events", + "Window": "persistentvolumes-events.png" + }, { "Id": "storageclasses", "Window": "storageclasses.png" }, + { + "Id": "storageclasses-yaml", + "Window": "storageclasses-yaml.png" + }, + { + "Id": "storageclasses-events", + "Window": "storageclasses-events.png" + }, { "Id": "volumeattachments", "Window": "volumeattachments.png" }, + { + "Id": "volumeattachments-yaml", + "Window": "volumeattachments-yaml.png" + }, + { + "Id": "volumeattachments-events", + "Window": "volumeattachments-events.png" + }, { "Id": "longhorn-nodes", "Window": "longhorn-nodes.png" }, + { + "Id": "longhorn-nodes-yaml", + "Window": "longhorn-nodes-yaml.png" + }, + { + "Id": "longhorn-nodes-events", + "Window": "longhorn-nodes-events.png" + }, { "Id": "longhorn-volumes", "Window": "longhorn-volumes.png" }, + { + "Id": "longhorn-volumes-yaml", + "Window": "longhorn-volumes-yaml.png" + }, + { + "Id": "longhorn-volumes-events", + "Window": "longhorn-volumes-events.png" + }, { "Id": "namespaces", "Window": "namespaces.png" }, { - "Id": "helm-charts", - "Window": "helm-charts.png" + "Id": "namespaces-yaml", + "Window": "namespaces-yaml.png" + }, + { + "Id": "namespaces-events", + "Window": "namespaces-events.png" + }, + { + "Id": "helm-releases", + "Window": "helm-releases.png" + }, + { + "Id": "helm-releases-yaml", + "Window": "helm-releases-yaml.png" + }, + { + "Id": "helm-releases-history", + "Window": "helm-releases-history.png" + }, + { + "Id": "helm-releases-values", + "Window": "helm-releases-values.png" + }, + { + "Id": "helm-releases-manifest", + "Window": "helm-releases-manifest.png" }, { "Id": "dapr-control-plane", "Window": "dapr-control-plane.png" }, + { + "Id": "dapr-control-plane-yaml", + "Window": "dapr-control-plane-yaml.png" + }, + { + "Id": "dapr-control-plane-events", + "Window": "dapr-control-plane-events.png" + }, + { + "Id": "dapr-control-plane-logs", + "Window": "dapr-control-plane-logs.png" + }, + { + "Id": "dapr-control-plane-terminal", + "Window": "dapr-control-plane-terminal.png" + }, { "Id": "dapr-sidecars", "Window": "dapr-sidecars.png" }, + { + "Id": "dapr-sidecars-yaml", + "Window": "dapr-sidecars-yaml.png" + }, + { + "Id": "dapr-sidecars-events", + "Window": "dapr-sidecars-events.png" + }, + { + "Id": "dapr-sidecars-logs", + "Window": "dapr-sidecars-logs.png" + }, + { + "Id": "dapr-sidecars-terminal", + "Window": "dapr-sidecars-terminal.png" + }, + { + "Id": "components", + "Window": "components.png" + }, + { + "Id": "components-yaml", + "Window": "components-yaml.png" + }, + { + "Id": "components-events", + "Window": "components-events.png" + }, { "Id": "configurations", "Window": "configurations.png" }, + { + "Id": "configurations-yaml", + "Window": "configurations-yaml.png" + }, + { + "Id": "configurations-events", + "Window": "configurations-events.png" + }, { "Id": "subscriptions", "Window": "subscriptions.png" }, { - "Id": "certificatesigningrequests", - "Window": "certificatesigningrequests.png" + "Id": "subscriptions-yaml", + "Window": "subscriptions-yaml.png" + }, + { + "Id": "subscriptions-events", + "Window": "subscriptions-events.png" + }, + { + "Id": "cnpg-clusters", + "Window": "cnpg-clusters.png" + }, + { + "Id": "cnpg-clusters-yaml", + "Window": "cnpg-clusters-yaml.png" + }, + { + "Id": "cnpg-clusters-events", + "Window": "cnpg-clusters-events.png" }, { "Id": "clusterrolebindings", "Window": "clusterrolebindings.png" }, + { + "Id": "clusterrolebindings-yaml", + "Window": "clusterrolebindings-yaml.png" + }, + { + "Id": "clusterrolebindings-events", + "Window": "clusterrolebindings-events.png" + }, { "Id": "clusterroles", "Window": "clusterroles.png" }, + { + "Id": "clusterroles-yaml", + "Window": "clusterroles-yaml.png" + }, + { + "Id": "clusterroles-events", + "Window": "clusterroles-events.png" + }, { "Id": "rolebindings", "Window": "rolebindings.png" }, + { + "Id": "rolebindings-yaml", + "Window": "rolebindings-yaml.png" + }, + { + "Id": "rolebindings-events", + "Window": "rolebindings-events.png" + }, { "Id": "roles", "Window": "roles.png" }, + { + "Id": "roles-yaml", + "Window": "roles-yaml.png" + }, + { + "Id": "roles-events", + "Window": "roles-events.png" + }, { "Id": "serviceaccounts", "Window": "serviceaccounts.png" }, + { + "Id": "serviceaccounts-yaml", + "Window": "serviceaccounts-yaml.png" + }, + { + "Id": "serviceaccounts-events", + "Window": "serviceaccounts-events.png" + }, { "Id": "customresourcedefinitions", "Window": "customresourcedefinitions.png" + }, + { + "Id": "customresourcedefinitions-yaml", + "Window": "customresourcedefinitions-yaml.png" + }, + { + "Id": "customresourcedefinitions-events", + "Window": "customresourcedefinitions-events.png" } ], "Skipped": [ @@ -232,10 +692,6 @@ "Id": "resourceslices", "Reason": "No rows." }, - { - "Id": "controllerrevisions", - "Reason": "No rows." - }, { "Id": "cronjobs", "Reason": "No rows." @@ -304,6 +760,10 @@ "Id": "networkpolicies", "Reason": "No rows." }, + { + "Id": "csidrivers", + "Reason": "No rows." + }, { "Id": "csistoragecapacities", "Reason": "No rows." @@ -317,11 +777,7 @@ "Reason": "No rows." }, { - "Id": "helm-releases", - "Reason": "No rows." - }, - { - "Id": "components", + "Id": "helm-charts", "Reason": "No rows." }, { @@ -333,7 +789,7 @@ "Reason": "No rows." }, { - "Id": "cnpg-clusters", + "Id": "certificatesigningrequests", "Reason": "No rows." }, { diff --git a/assets/screenshots/mutatingwebhookconfigurations-events.png b/assets/screenshots/mutatingwebhookconfigurations-events.png new file mode 100644 index 0000000..5915f26 Binary files /dev/null and b/assets/screenshots/mutatingwebhookconfigurations-events.png differ diff --git a/assets/screenshots/mutatingwebhookconfigurations-yaml.png b/assets/screenshots/mutatingwebhookconfigurations-yaml.png new file mode 100644 index 0000000..91b420a Binary files /dev/null and b/assets/screenshots/mutatingwebhookconfigurations-yaml.png differ diff --git a/assets/screenshots/namespaces-events.png b/assets/screenshots/namespaces-events.png new file mode 100644 index 0000000..030f8a5 Binary files /dev/null and b/assets/screenshots/namespaces-events.png differ diff --git a/assets/screenshots/namespaces-yaml.png b/assets/screenshots/namespaces-yaml.png new file mode 100644 index 0000000..f0ca0c2 Binary files /dev/null and b/assets/screenshots/namespaces-yaml.png differ diff --git a/assets/screenshots/nodes-events.png b/assets/screenshots/nodes-events.png new file mode 100644 index 0000000..6862ec3 Binary files /dev/null and b/assets/screenshots/nodes-events.png differ diff --git a/assets/screenshots/nodes-yaml.png b/assets/screenshots/nodes-yaml.png new file mode 100644 index 0000000..297f248 Binary files /dev/null and b/assets/screenshots/nodes-yaml.png differ diff --git a/assets/screenshots/persistentvolumeclaims-events.png b/assets/screenshots/persistentvolumeclaims-events.png new file mode 100644 index 0000000..eb53640 Binary files /dev/null and b/assets/screenshots/persistentvolumeclaims-events.png differ diff --git a/assets/screenshots/persistentvolumeclaims-yaml.png b/assets/screenshots/persistentvolumeclaims-yaml.png new file mode 100644 index 0000000..d626d03 Binary files /dev/null and b/assets/screenshots/persistentvolumeclaims-yaml.png differ diff --git a/assets/screenshots/persistentvolumes-events.png b/assets/screenshots/persistentvolumes-events.png new file mode 100644 index 0000000..d823cd1 Binary files /dev/null and b/assets/screenshots/persistentvolumes-events.png differ diff --git a/assets/screenshots/persistentvolumes-yaml.png b/assets/screenshots/persistentvolumes-yaml.png new file mode 100644 index 0000000..9c1be52 Binary files /dev/null and b/assets/screenshots/persistentvolumes-yaml.png differ diff --git a/assets/screenshots/poddisruptionbudgets-events.png b/assets/screenshots/poddisruptionbudgets-events.png new file mode 100644 index 0000000..ddd0dec Binary files /dev/null and b/assets/screenshots/poddisruptionbudgets-events.png differ diff --git a/assets/screenshots/poddisruptionbudgets-yaml.png b/assets/screenshots/poddisruptionbudgets-yaml.png new file mode 100644 index 0000000..4a8759a Binary files /dev/null and b/assets/screenshots/poddisruptionbudgets-yaml.png differ diff --git a/assets/screenshots/pods-events.png b/assets/screenshots/pods-events.png new file mode 100644 index 0000000..28c5826 Binary files /dev/null and b/assets/screenshots/pods-events.png differ diff --git a/assets/screenshots/pods-terminal.png b/assets/screenshots/pods-terminal.png new file mode 100644 index 0000000..95f2cd7 Binary files /dev/null and b/assets/screenshots/pods-terminal.png differ diff --git a/assets/screenshots/podtemplates-events.png b/assets/screenshots/podtemplates-events.png new file mode 100644 index 0000000..81fba79 Binary files /dev/null and b/assets/screenshots/podtemplates-events.png differ diff --git a/assets/screenshots/podtemplates-yaml.png b/assets/screenshots/podtemplates-yaml.png new file mode 100644 index 0000000..e87d06e Binary files /dev/null and b/assets/screenshots/podtemplates-yaml.png differ diff --git a/assets/screenshots/podtemplates.png b/assets/screenshots/podtemplates.png new file mode 100644 index 0000000..8a3823c Binary files /dev/null and b/assets/screenshots/podtemplates.png differ diff --git a/assets/screenshots/port-forwarding-yaml.png b/assets/screenshots/port-forwarding-yaml.png new file mode 100644 index 0000000..5dd2bc7 Binary files /dev/null and b/assets/screenshots/port-forwarding-yaml.png differ diff --git a/assets/screenshots/priorityclasses-events.png b/assets/screenshots/priorityclasses-events.png new file mode 100644 index 0000000..8c8c9f8 Binary files /dev/null and b/assets/screenshots/priorityclasses-events.png differ diff --git a/assets/screenshots/priorityclasses-yaml.png b/assets/screenshots/priorityclasses-yaml.png new file mode 100644 index 0000000..2ae4bc5 Binary files /dev/null and b/assets/screenshots/priorityclasses-yaml.png differ diff --git a/assets/screenshots/prioritylevelconfigurations-events.png b/assets/screenshots/prioritylevelconfigurations-events.png new file mode 100644 index 0000000..4afe3a0 Binary files /dev/null and b/assets/screenshots/prioritylevelconfigurations-events.png differ diff --git a/assets/screenshots/prioritylevelconfigurations-yaml.png b/assets/screenshots/prioritylevelconfigurations-yaml.png new file mode 100644 index 0000000..be49390 Binary files /dev/null and b/assets/screenshots/prioritylevelconfigurations-yaml.png differ diff --git a/assets/screenshots/replicasets-events.png b/assets/screenshots/replicasets-events.png new file mode 100644 index 0000000..a2d1ece Binary files /dev/null and b/assets/screenshots/replicasets-events.png differ diff --git a/assets/screenshots/replicasets-logs.png b/assets/screenshots/replicasets-logs.png new file mode 100644 index 0000000..1917983 Binary files /dev/null and b/assets/screenshots/replicasets-logs.png differ diff --git a/assets/screenshots/replicasets-pods.png b/assets/screenshots/replicasets-pods.png new file mode 100644 index 0000000..82fc1d3 Binary files /dev/null and b/assets/screenshots/replicasets-pods.png differ diff --git a/assets/screenshots/replicasets-terminal.png b/assets/screenshots/replicasets-terminal.png new file mode 100644 index 0000000..b8cc1be Binary files /dev/null and b/assets/screenshots/replicasets-terminal.png differ diff --git a/assets/screenshots/replicasets-yaml.png b/assets/screenshots/replicasets-yaml.png new file mode 100644 index 0000000..cc60edc Binary files /dev/null and b/assets/screenshots/replicasets-yaml.png differ diff --git a/assets/screenshots/rolebindings-events.png b/assets/screenshots/rolebindings-events.png new file mode 100644 index 0000000..95dd08a Binary files /dev/null and b/assets/screenshots/rolebindings-events.png differ diff --git a/assets/screenshots/rolebindings-yaml.png b/assets/screenshots/rolebindings-yaml.png new file mode 100644 index 0000000..7f7e8ca Binary files /dev/null and b/assets/screenshots/rolebindings-yaml.png differ diff --git a/assets/screenshots/roles-events.png b/assets/screenshots/roles-events.png new file mode 100644 index 0000000..40319b0 Binary files /dev/null and b/assets/screenshots/roles-events.png differ diff --git a/assets/screenshots/roles-yaml.png b/assets/screenshots/roles-yaml.png new file mode 100644 index 0000000..3352fb4 Binary files /dev/null and b/assets/screenshots/roles-yaml.png differ diff --git a/assets/screenshots/runtimeclasses-events.png b/assets/screenshots/runtimeclasses-events.png new file mode 100644 index 0000000..9873c3d Binary files /dev/null and b/assets/screenshots/runtimeclasses-events.png differ diff --git a/assets/screenshots/runtimeclasses-yaml.png b/assets/screenshots/runtimeclasses-yaml.png new file mode 100644 index 0000000..6b21d57 Binary files /dev/null and b/assets/screenshots/runtimeclasses-yaml.png differ diff --git a/assets/screenshots/secrets-data.png b/assets/screenshots/secrets-data.png new file mode 100644 index 0000000..1dfa00b Binary files /dev/null and b/assets/screenshots/secrets-data.png differ diff --git a/assets/screenshots/secrets-events.png b/assets/screenshots/secrets-events.png new file mode 100644 index 0000000..e25fb81 Binary files /dev/null and b/assets/screenshots/secrets-events.png differ diff --git a/assets/screenshots/secrets-yaml.png b/assets/screenshots/secrets-yaml.png new file mode 100644 index 0000000..2749033 Binary files /dev/null and b/assets/screenshots/secrets-yaml.png differ diff --git a/assets/screenshots/serviceaccounts-events.png b/assets/screenshots/serviceaccounts-events.png new file mode 100644 index 0000000..f3928a6 Binary files /dev/null and b/assets/screenshots/serviceaccounts-events.png differ diff --git a/assets/screenshots/serviceaccounts-yaml.png b/assets/screenshots/serviceaccounts-yaml.png new file mode 100644 index 0000000..6fe2f5c Binary files /dev/null and b/assets/screenshots/serviceaccounts-yaml.png differ diff --git a/assets/screenshots/servicecidrs-events.png b/assets/screenshots/servicecidrs-events.png new file mode 100644 index 0000000..603caf6 Binary files /dev/null and b/assets/screenshots/servicecidrs-events.png differ diff --git a/assets/screenshots/servicecidrs-yaml.png b/assets/screenshots/servicecidrs-yaml.png new file mode 100644 index 0000000..f3c0940 Binary files /dev/null and b/assets/screenshots/servicecidrs-yaml.png differ diff --git a/assets/screenshots/services-events.png b/assets/screenshots/services-events.png new file mode 100644 index 0000000..93c951d Binary files /dev/null and b/assets/screenshots/services-events.png differ diff --git a/assets/screenshots/services-pods.png b/assets/screenshots/services-pods.png new file mode 100644 index 0000000..e30c00b Binary files /dev/null and b/assets/screenshots/services-pods.png differ diff --git a/assets/screenshots/services-yaml.png b/assets/screenshots/services-yaml.png new file mode 100644 index 0000000..e17ac92 Binary files /dev/null and b/assets/screenshots/services-yaml.png differ diff --git a/assets/screenshots/statefulsets-events.png b/assets/screenshots/statefulsets-events.png new file mode 100644 index 0000000..52def3a Binary files /dev/null and b/assets/screenshots/statefulsets-events.png differ diff --git a/assets/screenshots/statefulsets-logs.png b/assets/screenshots/statefulsets-logs.png new file mode 100644 index 0000000..1c30e22 Binary files /dev/null and b/assets/screenshots/statefulsets-logs.png differ diff --git a/assets/screenshots/statefulsets-pods.png b/assets/screenshots/statefulsets-pods.png new file mode 100644 index 0000000..245fef6 Binary files /dev/null and b/assets/screenshots/statefulsets-pods.png differ diff --git a/assets/screenshots/statefulsets-terminal.png b/assets/screenshots/statefulsets-terminal.png new file mode 100644 index 0000000..040fdd1 Binary files /dev/null and b/assets/screenshots/statefulsets-terminal.png differ diff --git a/assets/screenshots/statefulsets-yaml.png b/assets/screenshots/statefulsets-yaml.png new file mode 100644 index 0000000..41d3379 Binary files /dev/null and b/assets/screenshots/statefulsets-yaml.png differ diff --git a/assets/screenshots/storageclasses-events.png b/assets/screenshots/storageclasses-events.png new file mode 100644 index 0000000..00cc1ed Binary files /dev/null and b/assets/screenshots/storageclasses-events.png differ diff --git a/assets/screenshots/storageclasses-yaml.png b/assets/screenshots/storageclasses-yaml.png new file mode 100644 index 0000000..f401cf2 Binary files /dev/null and b/assets/screenshots/storageclasses-yaml.png differ diff --git a/assets/screenshots/subscriptions-events.png b/assets/screenshots/subscriptions-events.png new file mode 100644 index 0000000..b115b0c Binary files /dev/null and b/assets/screenshots/subscriptions-events.png differ diff --git a/assets/screenshots/subscriptions-yaml.png b/assets/screenshots/subscriptions-yaml.png new file mode 100644 index 0000000..623d79d Binary files /dev/null and b/assets/screenshots/subscriptions-yaml.png differ diff --git a/assets/screenshots/validatingwebhookconfigurations-events.png b/assets/screenshots/validatingwebhookconfigurations-events.png new file mode 100644 index 0000000..489d956 Binary files /dev/null and b/assets/screenshots/validatingwebhookconfigurations-events.png differ diff --git a/assets/screenshots/validatingwebhookconfigurations-yaml.png b/assets/screenshots/validatingwebhookconfigurations-yaml.png new file mode 100644 index 0000000..b4c222d Binary files /dev/null and b/assets/screenshots/validatingwebhookconfigurations-yaml.png differ diff --git a/assets/screenshots/volume-files.png b/assets/screenshots/volume-files.png new file mode 100644 index 0000000..d4c0431 Binary files /dev/null and b/assets/screenshots/volume-files.png differ diff --git a/assets/screenshots/volumeattachments-events.png b/assets/screenshots/volumeattachments-events.png new file mode 100644 index 0000000..14755ca Binary files /dev/null and b/assets/screenshots/volumeattachments-events.png differ diff --git a/assets/screenshots/volumeattachments-yaml.png b/assets/screenshots/volumeattachments-yaml.png new file mode 100644 index 0000000..8b5c8e1 Binary files /dev/null and b/assets/screenshots/volumeattachments-yaml.png differ diff --git a/assets/screenshots/volumeattributesclasses-events.png b/assets/screenshots/volumeattributesclasses-events.png new file mode 100644 index 0000000..bba96f3 Binary files /dev/null and b/assets/screenshots/volumeattributesclasses-events.png differ diff --git a/assets/screenshots/volumeattributesclasses-yaml.png b/assets/screenshots/volumeattributesclasses-yaml.png new file mode 100644 index 0000000..3b1b93c Binary files /dev/null and b/assets/screenshots/volumeattributesclasses-yaml.png differ diff --git a/assets/screenshots/volumeattributesclasses.png b/assets/screenshots/volumeattributesclasses.png new file mode 100644 index 0000000..c331242 Binary files /dev/null and b/assets/screenshots/volumeattributesclasses.png differ diff --git a/data/com.maks_it.clusterconsole.metainfo.xml b/data/com.maks_it.clusterconsole.metainfo.xml index 89bbee1..076d7ef 100644 --- a/data/com.maks_it.clusterconsole.metainfo.xml +++ b/data/com.maks_it.clusterconsole.metainfo.xml @@ -65,6 +65,12 @@ + + https://github.com/MAKS-IT-COM/maksit-cluster-console/blob/v0.8.8/CHANGELOG.md + +

A ControllerRevision opens in the details pane. Its data values are shown as text.

+
+
https://github.com/MAKS-IT-COM/maksit-cluster-console/blob/v0.8.7/CHANGELOG.md diff --git a/packaging/flathub/manifest.md b/packaging/flathub/manifest.md index f56807a..93a11a1 100644 --- a/packaging/flathub/manifest.md +++ b/packaging/flathub/manifest.md @@ -9,7 +9,7 @@ Values for `com.maks_it.clusterconsole.yml` (or `.json`) at the top of the Flath | Homepage | [https://maks-it.com/](https://maks-it.com/) | | Project | `src/MaksIT.ClusterConsole.UI/MaksIT.ClusterConsole.UI.csproj` | | Target | `net10.0` | -| Source | Release tag on `https://github.com/MAKS-IT-COM/maksit-cluster-console` (currently `v0.8.7`) | +| Source | Release tag on `https://github.com/MAKS-IT-COM/maksit-cluster-console` (currently `v0.8.8`) | | Runtime | `org.freedesktop.Platform` | | SDK | `org.freedesktop.Sdk` | | SDK extension | `org.freedesktop.Sdk.Extension.dotnet10` | diff --git a/packaging/flathub/sources.md b/packaging/flathub/sources.md index 8071b64..a296d01 100644 --- a/packaging/flathub/sources.md +++ b/packaging/flathub/sources.md @@ -9,7 +9,7 @@ Upstream files stay in this repository. The Flathub build installs them from the | [src/MaksIT.ClusterConsole.UI/Assets/icon.svg](../../src/MaksIT.ClusterConsole.UI/Assets/icon.svg) | Icon, installed as `share/icons/hicolor/scalable/apps/com.maks_it.clusterconsole.svg`. | | [LICENSE.md](../../LICENSE.md) | Apache-2.0. Install to `$FLATPAK_DEST/share/licenses/com.maks_it.clusterconsole/` because the filename is `LICENSE.md`. | -Screenshot URLs in the metainfo use tag `v0.8.6`, where those images are stored. The `0.8.7` release entry points at tag `v0.8.7`. On a newer release, point `` at the tag that contains the screenshots and `` at that version. +Screenshot URLs in the metainfo use tag `v0.8.6`, where those images are stored. The `0.8.8` release entry points at tag `v0.8.8`. On a newer release, point `` at the tag that contains the screenshots and `` at that version. ## Pull request diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 66093b9..e295a00 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -3,7 +3,7 @@ latest enable enable - 0.8.7 + 0.8.8 Cluster Console Cluster Console MaksIT diff --git a/src/MaksIT.ClusterConsole.Shared/ResourceDocument.cs b/src/MaksIT.ClusterConsole.Shared/ResourceDocument.cs index 12287f2..6c1be68 100644 --- a/src/MaksIT.ClusterConsole.Shared/ResourceDocument.cs +++ b/src/MaksIT.ClusterConsole.Shared/ResourceDocument.cs @@ -111,7 +111,7 @@ public static class ResourceDocument { if (entries.Any(e => e.Key == prop.Key)) continue; - var raw = prop.Value?.GetValue() ?? prop.Value?.ToJsonString() ?? ""; + var raw = TextOf(prop.Value); if (!encoded) { entries.Add(new ResourceDataEntry(prop.Key, raw, false)); @@ -126,6 +126,16 @@ public static class ResourceDocument { } } + private static string TextOf(JsonNode? node) { + if (node is null) + return ""; + + if (node is JsonValue value && value.TryGetValue(out var text)) + return text ?? ""; + + return node.ToJsonString(); + } + private static void SetOrRemove(JsonObject document, string name, JsonObject map) { if (map.Count == 0) document.Remove(name); diff --git a/src/MaksIT.ClusterConsole.Shared/ScreenshotShoulder.cs b/src/MaksIT.ClusterConsole.Shared/ScreenshotShoulder.cs new file mode 100644 index 0000000..8acaf82 --- /dev/null +++ b/src/MaksIT.ClusterConsole.Shared/ScreenshotShoulder.cs @@ -0,0 +1,45 @@ +namespace MaksIT.ClusterConsole.Shared; + +/// +/// Right-shoulder tabs for the screenshot tour. +/// The page PNG is the Overview tab after the first row is selected. +/// Further shots walk every visible tab. Chat is never saved. +/// Add a navigator id to to leave more tabs out, +/// and to when that tab's text can be a secret. +/// Data and Helm values are always blurred. +/// +public static class ScreenshotShoulder { + public static bool Skip(string viewId, string tab) { + if (tab is DetailTab.Overview or DetailTab.Chat) + return true; + + return SkipByView.TryGetValue(viewId, out var tabs) && tabs.Contains(tab); + } + + public static bool Blur(string viewId, string tab) { + if (AlwaysBlur.Contains(tab)) + return true; + + return BlurByView.TryGetValue(viewId, out var tabs) && tabs.Contains(tab); + } + + /// + /// Tabs left out for one navigator id, besides Overview and Chat. + /// + private static readonly Dictionary> SkipByView = new(StringComparer.Ordinal); + + private static readonly HashSet AlwaysBlur = new(StringComparer.Ordinal) { + DetailTab.Data, + DetailTab.Values + }; + + /// + /// Extra tabs whose body is blurred for one navigator id. + /// + private static readonly Dictionary> BlurByView = new(StringComparer.Ordinal) { + ["secrets"] = new(StringComparer.Ordinal) { DetailTab.Yaml }, + ["configmaps"] = new(StringComparer.Ordinal) { DetailTab.Yaml }, + ["components"] = new(StringComparer.Ordinal) { DetailTab.Yaml }, + [ResourceCatalog.HelmReleasesId] = new(StringComparer.Ordinal) { DetailTab.Manifest } + }; +} diff --git a/src/MaksIT.ClusterConsole.Tests/ReleaseNotesTests.cs b/src/MaksIT.ClusterConsole.Tests/ReleaseNotesTests.cs index 88dd171..1a43fad 100644 --- a/src/MaksIT.ClusterConsole.Tests/ReleaseNotesTests.cs +++ b/src/MaksIT.ClusterConsole.Tests/ReleaseNotesTests.cs @@ -54,11 +54,12 @@ public class ReleaseNotesTests { [Fact] public void Shipped_notes_keep_older_work_out_of_the_current_version() { - var notes = ReleaseNotes.AddedSince(ReleaseNotes.Text(), seenVersion: null, currentVersion: "0.8.7"); + var notes = ReleaseNotes.AddedSince(ReleaseNotes.Text(), seenVersion: null, currentVersion: "0.8.8"); var note = Assert.Single(notes); - Assert.Equal("0.8.7", note.Version); - Assert.Contains(note.Added, line => line.Contains("Analyze issues", StringComparison.Ordinal)); + Assert.Equal("0.8.8", note.Version); + Assert.Contains(note.Added, line => line.Contains("ControllerRevision", StringComparison.Ordinal)); + Assert.DoesNotContain(note.Added, line => line.Contains("Analyze issues", StringComparison.Ordinal)); Assert.DoesNotContain(note.Added, line => line.Contains("drain dialog", StringComparison.Ordinal)); Assert.DoesNotContain(note.Added, line => line.Contains("Helm Charts", StringComparison.Ordinal)); Assert.DoesNotContain(note.Added, line => line.Contains("footer", StringComparison.OrdinalIgnoreCase)); diff --git a/src/MaksIT.ClusterConsole.Tests/ResourceCatalogTests.cs b/src/MaksIT.ClusterConsole.Tests/ResourceCatalogTests.cs index 653916e..56658de 100644 --- a/src/MaksIT.ClusterConsole.Tests/ResourceCatalogTests.cs +++ b/src/MaksIT.ClusterConsole.Tests/ResourceCatalogTests.cs @@ -281,6 +281,22 @@ public class ResourceCatalogTests { Assert.Null(edited["data"]); } + [Fact] + public void ResourceDocument_reads_nested_data_as_text() { + var revision = JsonNode.Parse(""" + { + "kind": "ControllerRevision", + "data": { "spec": { "replicas": 1 }, "note": "plain" } + } + """) as JsonObject; + + Assert.NotNull(revision); + var entries = ResourceDocument.ReadDataEntries(revision); + Assert.Equal(2, entries.Count); + Assert.Contains(entries, entry => entry.Key == "note" && entry.Value == "plain"); + Assert.Contains(entries, entry => entry.Key == "spec" && entry.Value.Contains("replicas", StringComparison.Ordinal)); + } + [Fact] public void ResourceDocument_prepares_apply_body_without_status() { var doc = JsonNode.Parse(""" diff --git a/src/MaksIT.ClusterConsole.Tests/ScreenshotShoulderTests.cs b/src/MaksIT.ClusterConsole.Tests/ScreenshotShoulderTests.cs new file mode 100644 index 0000000..1a92419 --- /dev/null +++ b/src/MaksIT.ClusterConsole.Tests/ScreenshotShoulderTests.cs @@ -0,0 +1,53 @@ +using MaksIT.ClusterConsole.Shared; + + +namespace MaksIT.ClusterConsole.Tests; + +public class ScreenshotShoulderTests { + [Theory] + [InlineData("pods", DetailTab.Chat)] + [InlineData("pods", DetailTab.Overview)] + [InlineData("secrets", DetailTab.Chat)] + public void Skips_chat_and_the_overview_page_shot(string viewId, string tab) { + Assert.True(ScreenshotShoulder.Skip(viewId, tab)); + } + + [Theory] + [InlineData("pods", DetailTab.Yaml)] + [InlineData("pods", DetailTab.Logs)] + [InlineData("pods", DetailTab.Terminal)] + [InlineData("nodes", DetailTab.Images)] + [InlineData("deployments", DetailTab.Pods)] + [InlineData("deployments", DetailTab.Events)] + [InlineData("helm-releases", DetailTab.History)] + [InlineData("helm-releases", DetailTab.Manifest)] + [InlineData("configmaps", DetailTab.Data)] + public void Keeps_every_other_visible_tab(string viewId, string tab) { + Assert.False(ScreenshotShoulder.Skip(viewId, tab)); + } + + [Theory] + [InlineData("secrets", DetailTab.Data)] + [InlineData("configmaps", DetailTab.Data)] + [InlineData("secrets", DetailTab.Yaml)] + [InlineData("configmaps", DetailTab.Yaml)] + [InlineData("components", DetailTab.Yaml)] + [InlineData("helm-releases", DetailTab.Values)] + [InlineData("helm-releases", DetailTab.Manifest)] + public void Blurs_secret_material(string viewId, string tab) { + Assert.True(ScreenshotShoulder.Blur(viewId, tab)); + } + + [Theory] + [InlineData("pods", DetailTab.Yaml)] + [InlineData("pods", DetailTab.Logs)] + [InlineData("pods", DetailTab.Terminal)] + [InlineData("pods", DetailTab.Overview)] + [InlineData("nodes", DetailTab.Images)] + [InlineData("deployments", DetailTab.Events)] + [InlineData("secrets", DetailTab.Overview)] + [InlineData("secrets", DetailTab.Events)] + public void Leaves_other_shoulder_text_readable(string viewId, string tab) { + Assert.False(ScreenshotShoulder.Blur(viewId, tab)); + } +} diff --git a/src/MaksIT.ClusterConsole.UI/Services/ScreenshotTour.cs b/src/MaksIT.ClusterConsole.UI/Services/ScreenshotTour.cs index a42a14c..10c30fa 100644 --- a/src/MaksIT.ClusterConsole.UI/Services/ScreenshotTour.cs +++ b/src/MaksIT.ClusterConsole.UI/Services/ScreenshotTour.cs @@ -1,8 +1,11 @@ using System.Text.Json; using System.Text.Json.Serialization; +using System.Runtime.InteropServices; using Avalonia; using Avalonia.Controls; +using Avalonia.Platform; using Avalonia.Threading; +using Avalonia.LogicalTree; using Avalonia.Media.Imaging; using MaksIT.ClusterConsole.Shared; using MaksIT.ClusterConsole.UI.Windows; @@ -78,7 +81,13 @@ internal static class ScreenshotTour { return false; await page.WaitUntilQuietAsync(20_000); - await Dispatcher.UIThread.InvokeAsync(page.EnsureRowSelected); + await Dispatcher.UIThread.InvokeAsync(() => { + if (page.IsResourceTable) + page.ShoulderCollapsed = false; + + page.SelectedTab = DetailTab.Overview; + page.EnsureRowSelected(); + }); await page.WaitUntilQuietAsync(20_000); await SettleAsync(settleMilliseconds); @@ -150,36 +159,33 @@ internal static class ScreenshotTour { } manifest.Shots.Add(Capture(window, options, id, manifest, saveCatalog: false)); - await CaptureFeatureExtrasAsync(window, model, page, options, manifest, id); + await CaptureShoulderTabsAsync(window, page, options, manifest, id); return true; } - private static async Task CaptureFeatureExtrasAsync( + private static async Task CaptureShoulderTabsAsync( Window window, - MainViewModel model, ClusterPageViewModel page, ScreenshotTourOptions options, Manifest manifest, string id) { - if (id == "pods") { - await CaptureTabAsync(window, page, options, manifest, DetailTab.Yaml, "pods-yaml"); - await CaptureTabAsync(window, page, options, manifest, DetailTab.Logs, "pods-logs"); + if (!page.IsResourceTable) + return; - if (model.ShowChat) - await CaptureTabAsync(window, page, options, manifest, DetailTab.Chat, "pods-chat"); + var tabs = await Dispatcher.UIThread.InvokeAsync(() => VisibleShoulderTabs(window)); + + if (tabs.Count == 0) { + manifest.Skipped.Add(new SkippedRecord { Id = id, Reason = "Shoulder tabs were not found." }); + + return; } - if (id == "nodes") - await CaptureTabAsync(window, page, options, manifest, DetailTab.Images, "nodes-images"); + foreach (var tab in tabs) { + if (ScreenshotShoulder.Skip(id, tab)) + continue; - if (id == "configmaps") - await CaptureTabAsync(window, page, options, manifest, DetailTab.Data, "configmaps-data"); - - if (id == ResourceCatalog.HelmReleasesId) { - await CaptureTabAsync(window, page, options, manifest, DetailTab.History, "helm-history"); - await CaptureTabAsync(window, page, options, manifest, DetailTab.Values, "helm-values"); - await CaptureTabAsync(window, page, options, manifest, DetailTab.Manifest, "helm-manifest"); + await CaptureTabAsync(window, page, options, manifest, id, tab); } if (id is "persistentvolumeclaims" or "persistentvolumes") @@ -191,16 +197,109 @@ internal static class ScreenshotTour { ClusterPageViewModel page, ScreenshotTourOptions options, Manifest manifest, - string tab, - string id) { + string viewId, + string tab) { await Dispatcher.UIThread.InvokeAsync(() => { page.EnsureRowSelected(); page.SelectedTab = tab; }); + + if (tab == DetailTab.Terminal) + await WaitForTerminalAsync(page); + await page.WaitUntilQuietAsync(20_000); await SettleAsync(options.SettleMilliseconds); - manifest.Shots.Add(Capture(window, options, id, manifest, saveCatalog: false)); - page.SelectedTab = DetailTab.Overview; + + PixelRect? redact = null; + + if (ScreenshotShoulder.Blur(viewId, tab)) + redact = await Dispatcher.UIThread.InvokeAsync(() => ShoulderBodyRect(window) ?? RightShoulder(window)); + + manifest.Shots.Add(Capture(window, options, viewId + "-" + tab.ToLowerInvariant(), manifest, saveCatalog: false, redact)); + await Dispatcher.UIThread.InvokeAsync(() => { + if (tab == DetailTab.Terminal) + page.Terminal.Close(); + + page.SelectedTab = DetailTab.Overview; + }); + } + + private static async Task WaitForTerminalAsync(ClusterPageViewModel page) { + var start = Environment.TickCount64; + + while (Environment.TickCount64 - start < 8_000) { + var status = page.Terminal.TerminalStatus; + + if (!status.Contains("Connecting", StringComparison.Ordinal) + && !status.StartsWith("Open a pod", StringComparison.Ordinal)) + return; + + await Task.Delay(100); + } + } + + private static IReadOnlyList VisibleShoulderTabs(Window window) { + var tabs = ShoulderTabs(window); + + if (tabs is null) + return []; + + var headers = new List(); + + foreach (var item in tabs.Items) { + if (item is not TabItem { IsVisible: true, Header: string header }) + continue; + + headers.Add(header); + } + + return headers; + } + + private static TabControl? ShoulderTabs(Window window) { + foreach (var tabs in window.GetLogicalDescendants().OfType()) { + var overview = false; + var yaml = false; + + foreach (var item in tabs.Items) { + if (item is not TabItem { Header: string header }) + continue; + + if (header == DetailTab.Overview) + overview = true; + else if (header == DetailTab.Yaml) + yaml = true; + } + + if (overview && yaml) + return tabs; + } + + return null; + } + + private static PixelRect? ShoulderBodyRect(Window window) { + if (ShoulderTabs(window)?.SelectedItem is not TabItem { Content: Control body }) + return null; + + var origin = body.TranslatePoint(new Point(0, 0), window); + + if (origin is null || body.Bounds.Width < 2 || body.Bounds.Height < 2) + return null; + + return new PixelRect( + (int)Math.Floor(origin.Value.X), + (int)Math.Floor(origin.Value.Y), + Math.Max(1, (int)Math.Ceiling(body.Bounds.Width)), + Math.Max(1, (int)Math.Ceiling(body.Bounds.Height))); + } + + private static PixelRect RightShoulder(Window window) { + var width = Math.Max(1, (int)Math.Ceiling(window.ClientSize.Width)); + var height = Math.Max(1, (int)Math.Ceiling(window.ClientSize.Height)); + var pane = Math.Min(width, 480); + + return new PixelRect(width - pane, 0, pane, height); } private static async Task CaptureVolumeFilesAsync( @@ -272,11 +371,12 @@ internal static class ScreenshotTour { ScreenshotTourOptions options, string id, Manifest manifest, - bool saveCatalog) { + bool saveCatalog, + PixelRect? redact = null) { var token = Token(id); var shot = new ShotRecord { Id = id, - Window = Save(window, Path.Combine(options.Directory, token + ".png")) + Window = Save(window, Path.Combine(options.Directory, token + ".png"), redact) }; if (saveCatalog && manifest.Catalog is null) @@ -285,7 +385,7 @@ internal static class ScreenshotTour { return shot; } - private static string? Save(Control? control, string path) { + private static string? Save(Control? control, string path, PixelRect? redact = null) { if (control is not { IsEffectivelyVisible: true }) return null; @@ -308,11 +408,158 @@ internal static class ScreenshotTour { using var bitmap = new RenderTargetBitmap(size, new Vector(96, 96)); bitmap.Render(control); Directory.CreateDirectory(Path.GetDirectoryName(path)!); - bitmap.Save(path, new PngBitmapEncoderOptions()); + + if (redact is { } region) + SaveRedacted(bitmap, size, region, path); + else + bitmap.Save(path, new PngBitmapEncoderOptions()); return Path.GetFileName(path); } + private static void SaveRedacted(RenderTargetBitmap bitmap, PixelSize size, PixelRect region, string path) { + using var output = new WriteableBitmap(size, new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Premul); + + using (var frame = output.Lock()) { + bitmap.CopyPixels(frame); + Redact(frame, region); + } + + output.Save(path, new PngBitmapEncoderOptions()); + } + + private static void Redact(ILockedFramebuffer frame, PixelRect region) { + var width = frame.Size.Width; + var height = frame.Size.Height; + var stride = frame.RowBytes; + var length = stride * height; + + if (length <= 0 || frame.Address == IntPtr.Zero) + return; + + var pixels = new byte[length]; + Marshal.Copy(frame.Address, pixels, 0, length); + + if (frame.Format.BitsPerPixel == 32 && stride >= width * 4) + BlurRegion(pixels, width, height, stride, region); + else + FillRegion(pixels, stride, region, width, height); + + Marshal.Copy(pixels, 0, frame.Address, length); + } + + private static void BlurRegion(byte[] pixels, int width, int height, int stride, PixelRect region) { + var left = Math.Clamp(region.X, 0, Math.Max(0, width - 1)); + var top = Math.Clamp(region.Y, 0, Math.Max(0, height - 1)); + var right = Math.Clamp(region.X + region.Width, left + 1, width); + var bottom = Math.Clamp(region.Y + region.Height, top + 1, height); + + if (right - left < 2 || bottom - top < 2) + return; + + const int radius = 16; + const int passes = 3; + var scratch = new byte[pixels.Length]; + + for (var pass = 0; pass < passes; pass++) { + BlurHorizontal(pixels, scratch, stride, left, right, top, bottom, radius); + BlurVertical(scratch, pixels, stride, left, right, top, bottom, radius); + } + } + + private static void BlurHorizontal( + byte[] source, + byte[] dest, + int stride, + int left, + int right, + int top, + int bottom, + int radius) { + var span = radius * 2 + 1; + + for (var y = top; y < bottom; y++) { + var row = y * stride; + + for (var x = left; x < right; x++) { + var b = 0; + var g = 0; + var r = 0; + var a = 0; + + for (var dx = -radius; dx <= radius; dx++) { + var sample = row + (Math.Clamp(x + dx, left, right - 1) * 4); + b += source[sample]; + g += source[sample + 1]; + r += source[sample + 2]; + a += source[sample + 3]; + } + + var pixel = row + (x * 4); + dest[pixel] = (byte)(b / span); + dest[pixel + 1] = (byte)(g / span); + dest[pixel + 2] = (byte)(r / span); + dest[pixel + 3] = (byte)(a / span); + } + } + } + + private static void BlurVertical( + byte[] source, + byte[] dest, + int stride, + int left, + int right, + int top, + int bottom, + int radius) { + var span = radius * 2 + 1; + + for (var y = top; y < bottom; y++) { + for (var x = left; x < right; x++) { + var b = 0; + var g = 0; + var r = 0; + var a = 0; + + for (var dy = -radius; dy <= radius; dy++) { + var sample = (Math.Clamp(y + dy, top, bottom - 1) * stride) + (x * 4); + b += source[sample]; + g += source[sample + 1]; + r += source[sample + 2]; + a += source[sample + 3]; + } + + var pixel = (y * stride) + (x * 4); + dest[pixel] = (byte)(b / span); + dest[pixel + 1] = (byte)(g / span); + dest[pixel + 2] = (byte)(r / span); + dest[pixel + 3] = (byte)(a / span); + } + } + } + + private static void FillRegion(byte[] pixels, int stride, PixelRect region, int width, int height) { + var left = Math.Clamp(region.X, 0, width); + var top = Math.Clamp(region.Y, 0, height); + var right = Math.Clamp(region.X + region.Width, left, width); + var bottom = Math.Clamp(region.Y + region.Height, top, height); + + for (var y = top; y < bottom; y++) { + for (var x = left; x < right; x++) { + var pixel = (y * stride) + (x * 4); + + if (pixel + 3 >= pixels.Length) + return; + + pixels[pixel] = 32; + pixels[pixel + 1] = 36; + pixels[pixel + 2] = 40; + pixels[pixel + 3] = 255; + } + } + } + private static string Token(string id) { var buffer = new char[id.Length]; diff --git a/src/MaksIT.ClusterConsole.UI/ViewModels/Cluster/ClusterPageViewModel.cs b/src/MaksIT.ClusterConsole.UI/ViewModels/Cluster/ClusterPageViewModel.cs index a2a8875..3454d21 100644 --- a/src/MaksIT.ClusterConsole.UI/ViewModels/Cluster/ClusterPageViewModel.cs +++ b/src/MaksIT.ClusterConsole.UI/ViewModels/Cluster/ClusterPageViewModel.cs @@ -1593,8 +1593,12 @@ public partial class ClusterPageViewModel : ObservableObject, IDisposable { while (true) { var details = _detailsLoad; - if (!_refreshBusy && details.IsCompleted) + if (!_refreshBusy && details.IsCompleted) { + // Accessing Exception marks a faulted load as observed, so the finalizer does not crash the process. + _ = details.Exception; + return; + } if (Environment.TickCount64 - start > timeoutMilliseconds) return; diff --git a/utils/tools/Invoke-Screenshots.ps1 b/utils/tools/Invoke-Screenshots.ps1 index 961805b..0097056 100644 --- a/utils/tools/Invoke-Screenshots.ps1 +++ b/utils/tools/Invoke-Screenshots.ps1 @@ -20,8 +20,10 @@ An empty resource table is skipped. With no -Views, the tour opens every navigator page except discovered custom resources, then Connections, - Settings → AI, volume files, and the YAML, logs, chat, data, images, - and Helm detail tabs. -Views limits the run to those navigator ids. + Settings → AI, and volume files. Each resource page waits for rows, selects the first one, and saves + the window on the Overview tab. It then saves every other visible right-shoulder tab. Chat is omitted. + Further omissions are per navigator id. Data, Helm values, secret and ConfigMap YAML, Dapr component + YAML, and Helm manifests are blurred in the PNG. -Views limits the run to those navigator ids. welcome is the shell before a cluster is opened. PNGs are 96 DPI device pixels, so a 1600x900 window is a 1600x900 file.