<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Affinity Manager Plugin: Tag-Based VM placement and grouping control]]></title><description><![CDATA[<h3>Affinity Manager Plugin</h3>
<p dir="auto"><strong>WHAT:</strong> In keeping with my previous project (Tag-Automation Plugin, <a href="https://xcp-ng.org/forum/topic/12265/tag-based-automation-plugin-tag-based-vm-performance-permission-management-via-assigned-tag-s">found here</a>), I am releasing the <strong>Affinity Manager Plugin</strong>, which is a fully tag-driven plugin for Xen Orchestra.  It is designed to provide VM placement and grouping controls based on assigned tags, which are managed by predefined tag rules.</p>
<hr />
<h4>PROGRAM FEATURES</h4>
<ul>
<li><strong>Host Affinity (<code>RunOn</code>)</strong> Run VMs on specific host group (e.g. a particular data center or set of hosts)</li>
<li><strong>Host Anti-Affinity (<code>NotOn</code>)</strong> Keep VMs off of specific host group</li>
<li><strong>VM Keep-Together (<code>KeepTogether</code>)</strong> Keep named group of VMs on the same host (follows Leader VM)</li>
<li><strong>VM Separation (<code>KeepApart</code>)</strong> Spread named group of VMs across unique hosts (best-effort)</li>
</ul>
<hr />
<h4>VM TAG SYNTAX</h4>
<p dir="auto">Apply tags to <strong>VMs</strong> in the XO UI:</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>VM TAG / RULE</th>
<th>EXAMPLE</th>
<th>MEANING</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>AM-RunOn_{HostGrpName}</code></td>
<td><code>AM-RunOn_P1-DC2-HOST</code></td>
<td>VM should run on hosts tagged <code>P1-DC2-HOST</code></td>
</tr>
<tr>
<td><code>AM-NotOn_{HostGrpName}</code></td>
<td><code>AM-NotOn_P2-DC1-HOST</code></td>
<td>VM should NOT run on hosts tagged <code>P2-DC1-HOST</code></td>
</tr>
<tr>
<td><code>AM-KeepTogether_{GrpName}</code></td>
<td><code>AM-KeepTogether_AppStack1</code></td>
<td>Keep all group VMs on same host (follows Leader VM)</td>
</tr>
<tr>
<td><code>AM-KeepApart_{GrpName}</code></td>
<td><code>AM-KeepApart_DBCluster1</code></td>
<td>Spread group VMs across unique hosts (best effort)</td>
</tr>
</tbody>
</table>
<blockquote>
<p dir="auto"><strong>Note:</strong> Multiple rules can be combined on a single VM. For example, a VM can have both<br />
<code>AM-RunOn_P1-DC1-HOST</code> and <code>AM-KeepTogether_WebCluster</code> simultaneously.</p>
</blockquote>
<hr />
<h4>HOST TAG SYNTAX</h4>
<p dir="auto">Apply tags to <strong>hosts</strong> in the XO UI (i.e. to define host groups):</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>EXAMPLE HOST TAG</th>
<th>POOL</th>
<th>LOCATION</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>P1-DC2-HOST</code></td>
<td>POOL-1</td>
<td>Data Center 2</td>
</tr>
<tr>
<td><code>P2-DC1-HOST</code></td>
<td>POOL-2</td>
<td>Data Center 1</td>
</tr>
</tbody>
</table>
<hr />
<h4>INSTALLATION</h4>
<ol>
<li>
<p dir="auto">Download the latest airgap release tarball from GitHub:<br />
<a href="https://github.com/johnezero/xo-affinity-manager/releases" target="_blank" rel="noopener noreferrer nofollow ugc">https://github.com/johnezero/xo-affinity-manager/releases</a></p>
</li>
<li>
<p dir="auto">SCP the tarball to your XOA:</p>
<pre><code class="language-bash">scp xo-affinity-manager-airgap-vX.X.X.tar.gz &lt;xoa-user&gt;@&lt;xoa-ip&gt;:/tmp/
</code></pre>
</li>
<li>
<p dir="auto">Create the plugin folder:</p>
<pre><code class="language-bash">sudo mkdir -p /usr/local/lib/node_modules/xo-server-affinity-manager
</code></pre>
</li>
<li>
<p dir="auto">Extract directly into the plugin directory:</p>
<pre><code class="language-bash">sudo tar -xzvf /tmp/xo-affinity-manager-airgap-vX.X.X.tar.gz -C /usr/local/lib/node_modules/xo-server-affinity-manager/ --strip-components=1
</code></pre>
</li>
<li>
<p dir="auto">Restart xo-server:</p>
<pre><code class="language-bash">sudo systemctl restart xo-server
</code></pre>
</li>
<li>
<p dir="auto">Verify registration:</p>
<pre><code class="language-bash">sudo journalctl -u xo-server -n 100 --no-pager | grep -A3 "affinity-manager"
</code></pre>
<p dir="auto">You should see:<br />
[INFO] xo-affinity-manager: Plugin factory called -- xo context: YES<br />
[INFO] xo-affinity-manager: Plugin loaded -- waiting for core started.<br />
xo:plugin INFO successfully register affinity-manager</p>
</li>
<li>
<p dir="auto">Enable and configure the plugin in XO:<br />
Settings -&gt; Plugins -&gt; affinity-manager -&gt; Enable</p>
</li>
</ol>
<hr />
<h4>CONFIGURATION</h4>
<p dir="auto">(XO &gt; Settings &gt; Plugins)</p>
<ul>
<li>
<p dir="auto"><strong>Enforcement Schedule</strong> — Run every 15 minutes, hourly, or daily (configurable)</p>
</li>
<li>
<p dir="auto"><strong>Dry Run Mode</strong> — Logs all intended actions without migrating anything (default: ON)</p>
</li>
<li>
<p dir="auto"><strong>Log Path</strong> — Configurable path to the log (Created automatically if it does not exist).</p>
</li>
<li>
<p dir="auto"><strong>Pool Safety</strong> — Cross-pool migration is always blocked (i.e. Plugin only migrates VMs within the same pool)</p>
</li>
<li>
<p dir="auto"><strong>Log Rotatate</strong> — Rotate/compress log files at 10 MB (keeping 3 archives)</p>
</li>
</ul>
<hr />
<h4>LINKS</h4>
<p dir="auto">GitHub:   <a href="https://github.com/johnezero/xo-affinity-manager" target="_blank" rel="noopener noreferrer nofollow ugc">https://github.com/johnezero/xo-affinity-manager</a></p>
<hr />
<p dir="auto"><strong>STANDARD DISCLAIMER HERE</strong></p>
<p dir="auto">This software is provided <strong>AS-IS</strong> without any express or implied warranty.<br />
While this plugin is being used in a production environment managing live VMs,<br />
you should always review the code and test it in a non-production environment<br />
before full deployment.<br />
Note: The plugin is designed to ONLY take action on VMs with specific <strong>predefined tags</strong> assigned -- all other VMs are never touched.<br />
Use Dry-Run mode to preview all changes before applying them.<br />
That said, as always - your mileage may vary...</p>
<p dir="auto"><img src="/forum/assets/uploads/files/1788399103619-johnezero-logo-small.png" alt="johnezero-logo-small.png" class=" img-fluid img-markdown" /></p>
]]></description><link>https://xcp-ng.org/forum/topic/12451/affinity-manager-plugin-tag-based-vm-placement-and-grouping-control</link><generator>RSS for Node</generator><lastBuildDate>Thu, 03 Sep 2026 02:03:01 GMT</lastBuildDate><atom:link href="https://xcp-ng.org/forum/topic/12451.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 03 Sep 2026 01:31:53 GMT</pubDate><ttl>60</ttl></channel></rss>