Repository navigation
Chart 1.0.5: working bundled MongoDB, upgrades that keep the release, OPC Router 5.7 - #14
Draft
etoensfeldt wants to merge 40 commits into
Draft
etoensfeldt wants to merge 40 commits into
etoensfeldt wants to merge 40 commits into
Conversation
Windows checkouts with core.autocrlf would otherwise turn the CI scripts into CRLF files that bash cannot run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every pull request and every push to main now runs chart-testing's lint on changed charts and renders the chart with each values file under .github/ci/values for Kubernetes 1.25, 1.30 and 1.34. The rendered manifests are validated with kubeconform in strict mode, with Helm 3 and Helm 4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moves to actions/checkout v7, azure/setup-helm v5 with Helm 3.22.0 and chart-releaser-action v1.7.0, grants the token write access explicitly and skips chart versions that are already released. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ct lint runs helm dependency build, which refuses a dependency whose repository is not configured. The check stayed green so far only because no pull request changed the chart. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pull requests now also run helm-unittest against the chart. The tests live in charts/opc-router/tests and are excluded from the package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bitnami removed the versioned MongoDB tags from docker.io/bitnami, so a fresh install could no longer pull its database. The chart now pins the mongodb subchart to 10.31.5, the version every 1.0.x release shipped, vendors it together with a matching Chart.lock, and pulls MongoDB 4.4.15 from docker.io/bitnamilegacy, the newest 4.4 build kept there. Releases are packaged from the vendored subchart instead of resolving it from a third-party chart index at release time, and only versions that are not tagged yet are released. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Chart versions up to 1.0.4 put the chart and app version into the Deployment's selector. Kubernetes does not allow a selector to change, so every chart upgrade failed with "field is immutable". The router's selector is now read from the release's existing Deployment and reused unchanged. New releases get selector labels without any version (name, instance and component). The pod labels are built from the selector labels first, so the selector always matches, and the Service selects the pods with the same labels. This also removes the duplicate instance label and the StatefulSet pod-name label that made the Deployment invalid YAML with mongodb.deploy=false. lookup returns nothing under helm template, so tools that render offline see the new labels and need to replace the Deployment once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two routers on one embedded database cannot both start: the second one finds the data directory locked and, without a stage-2 policy, keeps running without answering. With mongodb.deploy=false the Deployment now uses the Recreate strategy, so the old pod is gone before the new one starts. With a separate MongoDB the strategy stays unset as before, so a strategy patched onto a live Deployment is kept; updateStrategy sets any strategy explicitly. The router container also gets S6_BEHAVIOUR_IF_STAGE2_FAILS=2 unless envVars already sets it: a failed startup step then stops the container and Kubernetes restarts it, instead of leaving it running and silent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The chart bound the router's service account to the namespace admin role whenever it created the account, although only the experimental project auto-update uses the Kubernetes API, to restart the router pod after a new commit. Clusters whose rules forbid such a binding had to turn off the service account. The admin binding is gone. With the auto-update a Role allows listing and deleting pods, bound under a new name because a binding's role reference cannot change. Without the auto-update no role is created and no API token is mounted into the pod. The restart now selects only this release's router pods instead of every pod with the chart's name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The unanchored "tests/" pattern also excluded templates/tests, so the chart's own connection test would have been missing from the package. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The project clone and auto-update containers used alpine/git:latest and bitnami/kubectl:latest; Bitnami now publishes only latest tags for free. They now default to alpine/git v2.47.2 and registry.k8s.io/kubectl v1.33.0, which has no shell, so the proxy is started through the image's kubectl entrypoint. helperResources sets requests and limits for all helper containers, and the connection test gets a configurable image and resources, so clusters that reject containers without limits can run every pod of the chart. The connection test now asks the runtime's health route instead of only opening the web port. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The data volume defaulted to 100M and the log volume to 1Gi. With the embedded database both filled up in production: MongoDB stopped when it could no longer write its log, and the web management timed out. Capacities now default to empty. A configured capacity is used as is. Otherwise an existing claim keeps its current size, because a bound claim cannot shrink and can only grow with a storage class that allows expansion. A new install gets 10Gi for data and 6Gi for logs with the embedded database, and 1Gi and 4Gi with a separate MongoDB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With the embedded database, the image's startup check writes into /var/log/opcrouter/mongodb before a later step creates that folder. A new, empty log volume next to an existing database therefore made every start fail, for example after the log claim was replaced. With mongodb.deploy=false an init container from the router image now creates the folder and hands it to the image's mongodb user. Images without that user have no embedded database and are left untouched. prepareLogFolder=false switches the step off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
service.extraPorts opens further ports on the router container and the Service, for example a project's OPC UA server. extraEnv takes native EnvVar entries, so a value can come from a Secret; it also counts for the startup-failure default. extraVolumes, extraVolumeMounts and extraInitContainers cover what clusters so far patched into the rendered manifests, such as an odbc.ini for the ODBC plug-in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
probes.enabled adds a startup, a readiness and a liveness probe. Startup and liveness ask /health/runtime/live, readiness /health/runtime/ready, so a runtime that runs but is not ready is taken out of rotation, not restarted. The startup budget is ten minutes for a first start that migrates the embedded database. With HTTPS the probes use the HTTPS web port, because port 8080 only redirects. The probes stay off by default: builds before 5.3.6001 and 5.4.5005 answer every address with the start page, so a probe there passes without checking anything. With probes on, the service publishes a pod that is not ready, so the web management stays reachable while the runtime is not. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
project.importMode chooses how the project replaces the configuration at every start. clear, the default, deletes the configuration before the import, as the chart always did. On 5.5, 5.6, 5.7 and later 5.4 builds that step stops the web management from starting, a known product defect; overwrite imports over the existing configuration instead and works on every build from 5.1.5001 on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A secret volume has no type field; strict schema validation rejects the Deployment as soon as HTTPS or an SSH key is configured. The CI matrix now renders the web management over HTTPS with login, and the runtime image with its embedded database, which renders cleanly since the pod labels are merged without duplicates. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With mongodb.replicaCount above 1 the chart rendered a connection string the Deployment could not even parse, and the router supports only a single-member replica set anyway: several hosts stop it from starting, and losing a member of a larger set stalls it. The chart now says so when it renders. The connection string of the single member is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With a LoadBalancer service the notes sent users to the bundled MongoDB's external service and port, and with the embedded database they failed to render at all, which made every such install fail. They now name the router's service and port, use https when the web management serves HTTPS, forward a local port to the service instead of a looked-up pod, and warn while the web management has no login. The securityContext text in the values now states what the image measurably needs instead of suggesting settings that stop it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The redundancy mode was never wired up: no template used the helper for a second router's name, the two older selector helpers or the redundant project clone, and the values they read do not exist. Every CI values file renders the same as before. The selector of an existing release, which may still carry the old redundancy label, is read from the cluster and stays as it is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The router image writes the embedded MongoDB's log without rotating it, so on a long-running install it grows until the log volume is full and the database stops. mongodbLogRotation.enabled adds a container from the router image that renames the log once it exceeds maxSizeMB, asks mongod to reopen its log path, and keeps the newest keepFiles rotated files. Off by default; only with the embedded database. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The README now covers the upgrade to 1.0.5 in its three Helm modes, the repair of a MongoDB pod stuck on the removed Bitnami image, what tools that render without the cluster have to do, the rollback trap and the move to OPC Router 5.7. It states what the router needs from a cluster, what the two volumes hold and how to size them, how pods are replaced and what that costs, the health probes and their minimum builds, security defaults, exact image tags, managed clusters with admission policies, and the new extension points. The parameter tables list every value. Corrected: the switch to the runtime image, the key of the SSH secret, and the MongoDB redundancy mode, which never worked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The CI matrix gains a values file for a managed cluster: resources on every container, no service account permissions, an internal load balancer with an extra port, a dedicated node pool, probes, the log rotation and the runtime image with its embedded database. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
chart-testing lints values.yaml with yamllint, which rejects trailing spaces and a missing final newline. Whitespace only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The role allows deleting any pod of the namespace, so the restart's label selector is what keeps the auto-update to its own release. No test noticed when the release label was dropped from it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MongoDB reads the replica set key as a key file of base64 characters; the hyphens in the placeholder would keep it from starting if the file were ever installed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With probes on, the service also routed to the new pod while it was still starting. During a rolling update with the bundled MongoDB, about one in three requests in that window was refused, up to five seconds in a row. Without that, no request failed while both routers ran, because the old one served until its successor was ready. service.publishNotReadyAddresses now defaults to empty: the service routes to a router that is not ready only when the pod is replaced with Recreate, where a rollout has a gap anyway and reaching the web management of a runtime that is not ready matters more. An explicit true or false still wins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A rollback replaces a running MongoDB pod with one that cannot start. Tools that render without the cluster also have to recreate the Service, whose merged selector otherwise selects no pod. Releases from 1.0.0 and 1.0.1 move to OPC Router 5.3 unless they set image.tag. The replica set key takes only base64 characters. The probe and update sections give the measured behaviour of a rolling update. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An upgrade adds the log folder init container to every installation with the embedded database. Without resources it was rejected on clusters whose admission policy demands limits, after Recreate had already stopped the running router. It now takes the router's security context and, unless helperResources is set, the router's resources; as an init container it does not raise the pod's requests. The probe comment no longer claims behaviour after a license expiry, which was not measured. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With serviceAccount.create=false the role was bound to the namespace's default account, which every other pod without an account of its own shares, so all of them could delete the namespace's pods. The role is now bound only to the chart's account or to the one named in serviceAccount.name, as chart 1.0.4 bound nothing in that case either. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The README now lists every effect of the upgrade on a running release: the replaced router and MongoDB pods, the pinned helper images, the init container's resources, the stricter helm test and the visible failure of a broken import. It warns against --atomic, names the deployed revision for the repair, orders the move to 5.7 so the backup and the import mode come first, describes Recreate and the multi-node stall as measured, fixes the du command and the seconds of the overlap, and explains which account the auto-update's role is bound to. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With MongoDB authentication and generated passwords the MongoDB chart refuses every upgrade until the current passwords are passed. Since no upgrade between 1.0.x versions got past the selector before, this message will be new to most users; the README shows how to read the values from the release's Secret and under which keys to pass them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Service takes the kept selector from the same helper as the Deployment, and a volume the chart creates takes its size from the same helper as its claim. No test noticed when either second caller stopped using its helper. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With claims.*.storageVolume.createVolume and the default volume type local, the API rejected the volume, because a local volume lives on one node and needs node affinity; the install failed after it had started. The chart now stops before that and names the value to set. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Measured on three nodes: a volume pinned to one node brings every new pod back to it, so rolling updates and Recreate work as on one node, but the router cannot start while that node is unavailable. Storage that is local to a node without node affinity hands a moved pod an empty /data. The multi-node stall applies to volumes that move between nodes, such as cloud disks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The probes, the service setting for pods that are not ready and their helpers, tests and documentation leave 1.0.5; chart 2.0 brings them back together with its other changes to how the router pod is run. Reverting this commit restores them as they were tested. helm test keeps asking the runtime's readiness route. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Chart 1.0.5 installs OPC Router 5.7, so a release without an image tag of its own moves from 5.3 to 5.7 with the upgrade. The README now covers the move as part of the upgrade: the backup, the embedded database's one-way migration to MongoDB 8, Recreate so that 5.3 and 5.7 do not share the bundled database, and how to stay on 5.3. The project import keeps its default clear, which stops the web management of 5.5 to 5.7. The installation notes now warn whenever a project is imported that way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The router initiates the MongoDB replica set itself when it gets there first, and the set's only member then carries the pod's short host name, which resolves only inside the MongoDB pod. Who wins that race is a matter of timing. OPC Router 5.3 did not mind; 5.7 follows the member names, finds no primary and its web management never starts, also on a fresh install with the defaults. With directConnection=true the router talks to the one member it was given. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tion With the clear import on 5.5 to 5.7 the pod keeps running and nothing answers; it does not restart, because the failing web management is restarted inside the container. The upgrade notes now also say why the router connects to the bundled MongoDB directly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The router mounts its two volumes as ReadWriteOnce whether MongoDB is bundled, external or embedded. A rolling update starts the new pod next to the old one: on another node it waits for volumes the old pod still holds, and the rollout stalls for good on node-attached disks such as Azure Disk or EBS. Until now the chart used Recreate only with the embedded database. Recreate is now the default in every mode. A rolling update is safe only with a separate MongoDB and on a single node, with volumes pinned to a node, or with volumes not attached to nodes; updateStrategy still selects it there. An existing release switches without an API error. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Changes
bitnamilegacy/mongodb:4.4.15, which opens the old 4.4.11 data. The subchart is pinned to 10.31.5.directConnection=true. Without it, OPC Router 5.7 finds no primary whenever the router initiated the replica set before the MongoDB chart did.Recreatewith the bundled MongoDB; git projects needproject.importMode=overwrite;image.tag=5.3stays on 5.3.S6_BEHAVIOUR_IF_STAGE2_FAILS=2.Recreatein every mode, because itsReadWriteOncevolumes stall a rolling update on another node;updateStrategy.type=RollingUpdatestays available.service.extraPorts,extraEnv,extraVolumes/extraVolumeMounts,extraInitContainers.type, a node-affinity guard for chart-createdlocalvolumes,mongodb.replicaCount > 1refused.ct lint, helm-unittest, and rendering validated with kubeconform against Kubernetes 1.25/1.30/1.34, with Helm 3 and 4. The release workflow is updated.