janhoy opened a new pull request, #894:
URL: https://github.com/apache/solr-operator/pull/894
🤖 AI assisted 🤖
Closes #691
> Stacked on #827, which this needs for Solr version detection. Review that
first. Only the last commit belongs to this PR.
**Problem.** Solr picks replica placement with a cluster-wide plugin and
defaults to `SimplePlacementFactory`. To use anything else, including
`AffinityPlacementFactory`, you either maintain a full custom solr.xml or POST
to `/api/cluster/plugin` by hand after every cluster rebuild. Neither is
declarative, and the custom solr.xml route costs you the operator-generated
solr.xml entirely.
**Solution.** A new SolrCloud section:
```yaml
spec:
replicaPlacementFactory:
class: org.apache.solr.cluster.placement.plugins.AffinityPlacementFactory
config:
minimalFreeDiskGB: 10
prioritizedFreeDiskGB: 200
```
The operator applies this through `/api/cluster/plugin` once the cloud has a
ready pod, under the reserved name `.placement-plugin`. Removing the section
removes the plugin. Changes need no pod restart. Also exposed as the Helm value
`solrOptions.replicaPlacementFactory`.
**Why the API and not solr.xml.** The issue proposed rendering
`<replicaPlacementFactory>` into the generated solr.xml. Two findings moved me
off that:
- Declaring any cluster plugin in solr.xml requires
`solr.cluster.plugin.edit.enabled=false`, or `NodeConfig` throws at startup and
no node comes up. That property then disables the `/cluster/plugin` edit API
cluster-wide, for cluster singletons and custom plugins too. The operator would
be imposing a cluster-wide restriction to deliver one feature.
- `AffinityPlacementConfig` has `long`, `Integer`, `Boolean` and three
`Map<String,String>` fields, so solr.xml would need correct type tags plus
nested `<lst>` rendering. Over the API the config is JSON and passes through
untouched.
**Design notes.**
- `config` is arbitrary JSON via `x-kubernetes-preserve-unknown-fields`, so
any plugin's options work with no per-option plumbing. The tradeoff is no
schema validation of keys.
- Re-application is driven by a hash of the desired plugin in
`status.appliedReplicaPlacementFactory`, so Solr is called only when the spec
changes. The hash normalises the JSON first, so reformatting the config does
not trigger a reapply. A cloud configuring no plugin never calls Solr at all.
- Solr 9+ is required, gated with `SolrVersionAtLeast` from #827. On Solr 8
the setting is ignored with a warning event rather than retried.
- No security.json change needed. The endpoint requires `COLL_EDIT_PERM`,
which the operator's k8s role already holds through `collection-admin-edit`.
**Also fixes a latent panic in `CallCollectionsApiV2`.** It passed a nil
`*bytes.Buffer` as the request body, which is a non-nil `io.Reader` wrapping a
nil pointer, so `http.NewRequestWithContext` panicked calling `Len()` on it. No
previous caller passed a nil body, so this GET was the first to hit it. The
panic aborted the whole reconcile, leaving the SolrCloud stuck at zero ready
replicas in its status. Present on main, independent of this feature, and easy
to split out if preferred.
**Testing.** Five unit tests cover plugin construction, JSON passthrough
including nested objects and non-string types, hash stability against
reformatting, and rejection of invalid JSON. The full unit suite passes, as do
`check-manifests`, `check-generated`, `check-mod`, `check-format`, `vet` and
`check-helm`.
Manually verified on a kind cluster with Solr 9.11 and the e2e harness:
- the config reaches Solr intact, integers and booleans included
- changing the config updates the existing plugin, confirmed by `GET
/api/cluster/plugin`
- removing the section removes the plugin and clears the status hash
- a Solr 8.11 cloud gets the `ReplicaPlacementPluginUnsupported` warning and
no retry loop
- five forced reconciles produce no additional calls to Solr
That manual run is also what surfaced both bugs above, so the API call is
still worth an e2e spec. I have not added one.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]