Every one of these raises NameError if its code path is reached: - nodeapply: run_automation accumulated into an exitcode that only existed in run(), so any automation error crashed instead of being reported. It now keeps and returns its own, tracked separately from the exit code of the ssh commands: the early exit after the spawn loop tests that one, and folding automation failures into it would exit with children already running and their pipes abandoned. Both are reported at the real exits. - nodeconsole: redraw() reads firstnodename, which was local to do_screenshot(); promote it to a module global like the other drawing state. - nodedeploy: the redeploy path appended to a lockednodes list that did not exist yet. The block that follows re-reads the same lock state and acts on it, so drop the dead duplicate. - samples/nodeattrib_from_switch.py, misc/filterpasswd: missing import sys. - xcc3: fixuuid was never imported. xcc imports xcc3, so take a local copy the way the smm handler does instead of creating an import cycle. - httpapi: the async session call still passed the WSGI-era env and an extra argument to handle_async(), which has taken only querydict since the aiohttp port. Calling it correctly exposed that handle_async() registers an AsyncSession before raising on the discontinued long poll path, so every request to it would leak a session that is never reaped. It now only creates one when there is a websocket handler to yield it to. - messages: the InputFirmwareUpdate.filename property checked self.filebynode[node] with no node in scope. __init__ already validates every expanded path and nodefile() rechecks per node, so drop the checks. - pam: drop the python2 branches referencing unicode and raw_input. The server has been python3 only since the asyncio port. - cooltera: the sensor-name listing referenced a nonexistent sensors dict. The available sensors depend on the model, which is only known after reading the device, so list them from the same status data the readings use. - deltapdu, eatonpdu, geist: the not-implemented response in update() used node outside the loop, unlike retrieve() in the same files and unlike raritan/enlogic. - confluentdbgcli: stray self. on a module-level socket connect.
Confluent
Confluent is a software package to handle essential bootstrap and operation of scale-out server configurations. It supports stateful and stateless deployments for various operating systems.
Check this page for a more detailed list of features.
Confluent is the modern successor of xCAT. If you're coming from xCAT, check out this comparison.
Documentation
Confluent documentation is hosted on: https://xcat2.github.io/confluent-docs/
Download
Get the latest version from: https://xcat2.github.io/confluent-docs/downloads/
Check release notes on: https://xcat2.github.io/confluent-docs/release_notes/
Open Source License
Confluent is made available under the Apache 2.0 license: https://opensource.org/license/apache-2-0
Developers
Want to help? Submit a Pull Request.
Versioning and releases
The top-level VERSION file names the release the current branch is working toward. Build scripts
call ./mkversion, which turns it into the version stamped on packages: the tag itself on a release
tag (4.0.1), otherwise a development version (4.0.1.dev5+gdeadbee, or 4.0.1~dev5+gdeadbee for
the packages that have no setup.py).
mkversion also derives a version from the newest tag reachable from HEAD and uses whichever is
higher, so forgetting to bump VERSION after tagging the current branch cannot walk the version
backwards. Staying ahead of tags on other branches is what VERSION itself is for: patch releases
are tagged on release branches, which master never sees.
Cutting a new series:
- Land the release commit on master and tag
X.Y.0there. - Create branch
X.Yfrom that tag; it inheritsVERSION=X.Y.0. - Only then bump
VERSIONon master. Doing it before step 2 leaves the release branch on the wrong series.
Patch releases land on branch X.Y and are tagged X.Y.Z there; no VERSION edit is needed.