network: convert hook script to take a network port XML

When (un)plugging an interface into a network, the 'plugged'
and 'unplugged' operations are invoked in the hook script.

The data provided to the script contains the network XML, the
domain XML and the domain interface XML. When we strictly split the
drivers up this will no longer be possible and thus breakage is
unavoidable. The hook scripts are not considered to be covered by the
API guarantee so this is OK.

To avoid existing scripts taking the wrong action, the existing
operations are changed to 'port-created' and 'port-deleted'
instead. These will receive the network XML and the network port
XML.

Reviewed-by: Laine Stump <laine@laine.org>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2018-12-19 15:36:04 +00:00
parent 04ada2f841
commit 6394cf9768
4 changed files with 26 additions and 33 deletions

View File

@ -91,10 +91,8 @@
&lt;/network&gt; &lt;/network&gt;
&lt;/hookData&gt;</pre> &lt;/hookData&gt;</pre>
<p>In the case of an interface <p>In the case of an network port being created / deleted, the network
being plugged/unplugged to/from the network, the network XML will be XML will be followed with the full XML description of the port:</p>
followed with the full XML description of the domain containing the
interface that is being plugged/unplugged:</p>
<pre>&lt;hookData&gt; <pre>&lt;hookData&gt;
&lt;network&gt; &lt;network&gt;
@ -102,11 +100,11 @@
&lt;uuid&gt;afca425a-2c3a-420c-b2fb-dd7b4950d722&lt;/uuid&gt; &lt;uuid&gt;afca425a-2c3a-420c-b2fb-dd7b4950d722&lt;/uuid&gt;
... ...
&lt;/network&gt; &lt;/network&gt;
&lt;domain type='$domain_type' id='$domain_id'&gt; &lt;networkport&gt;
&lt;name&gt;$domain_name&lt;/name&gt; &lt;uuid&gt;5d744f21-ba4a-4d6e-bdb2-30a35ff3207d&lt;/uuid&gt;
&lt;uuid&gt;afca425a-2c3a-420c-b2fb-dd7b4950d722&lt;/uuid&gt; ...
... &lt;plug type='direct' dev='ens3' mode='vepa'/&gt;
&lt;/domain&gt; &lt;/networkport&gt;
&lt;/hookData&gt;</pre> &lt;/hookData&gt;</pre>
<p>Please note that this approach is different from other cases such as <p>Please note that this approach is different from other cases such as
@ -296,15 +294,15 @@
<pre>/etc/libvirt/hooks/network network_name stopped end -</pre></li> <pre>/etc/libvirt/hooks/network network_name stopped end -</pre></li>
<li>Later, when network is started and there's an interface from a <li>Later, when network is started and there's an interface from a
domain to be plugged into the network, the hook script is called as:<br/> domain to be plugged into the network, the hook script is called as:<br/>
<pre>/etc/libvirt/hooks/network network_name plugged begin -</pre> <pre>/etc/libvirt/hooks/network network_name port-created begin -</pre>
Please note, that in this case, the script is passed both network and Please note, that in this case, the script is passed both network and
domain XMLs on its stdin.</li> port XMLs on its stdin.</li>
<li>When network is updated, the hook script is called as:<br/> <li>When network is updated, the hook script is called as:<br/>
<pre>/etc/libvirt/hooks/network network_name updated begin -</pre></li> <pre>/etc/libvirt/hooks/network network_name updated begin -</pre></li>
<li>When the domain from previous case is shutting down, the interface <li>When the domain from previous case is shutting down, the interface
is unplugged. This leads to another script invocation:<br/> is unplugged. This leads to another script invocation:<br/>
<pre>/etc/libvirt/hooks/network network_name unplugged begin -</pre> <pre>/etc/libvirt/hooks/network network_name port-deleted begin -</pre>
And again, as in previous case, both network and domain XMLs are passed And again, as in previous case, both network and port XMLs are passed
onto script's stdin.</li> onto script's stdin.</li>
</ul> </ul>

View File

@ -205,14 +205,13 @@ networkObjFromNetwork(virNetworkPtr net)
static int static int
networkRunHook(virNetworkObjPtr obj, networkRunHook(virNetworkObjPtr obj,
virDomainDefPtr dom, virNetworkPortDefPtr port,
virDomainNetDefPtr iface,
int op, int op,
int sub_op) int sub_op)
{ {
virNetworkDefPtr def; virNetworkDefPtr def;
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
char *xml = NULL, *net_xml = NULL, *dom_xml = NULL; char *xml = NULL;
int hookret; int hookret;
int ret = -1; int ret = -1;
@ -226,11 +225,9 @@ networkRunHook(virNetworkObjPtr obj,
virBufferAddLit(&buf, "<hookData>\n"); virBufferAddLit(&buf, "<hookData>\n");
virBufferAdjustIndent(&buf, 2); virBufferAdjustIndent(&buf, 2);
if (iface && virDomainNetDefFormat(&buf, iface, NULL, 0) < 0)
goto cleanup;
if (virNetworkDefFormatBuf(&buf, def, 0) < 0) if (virNetworkDefFormatBuf(&buf, def, 0) < 0)
goto cleanup; goto cleanup;
if (dom && virDomainDefFormatInternal(dom, NULL, 0, &buf, NULL) < 0) if (port && virNetworkPortDefFormatBuf(&buf, port) < 0)
goto cleanup; goto cleanup;
virBufferAdjustIndent(&buf, -2); virBufferAdjustIndent(&buf, -2);
@ -256,8 +253,6 @@ networkRunHook(virNetworkObjPtr obj,
cleanup: cleanup:
virBufferFreeAndReset(&buf); virBufferFreeAndReset(&buf);
VIR_FREE(xml); VIR_FREE(xml);
VIR_FREE(net_xml);
VIR_FREE(dom_xml);
return ret; return ret;
} }
@ -2777,7 +2772,7 @@ networkStartNetwork(virNetworkDriverStatePtr driver,
/* Run an early hook to set-up missing devices. /* Run an early hook to set-up missing devices.
* If the script raised an error abort the launch. */ * If the script raised an error abort the launch. */
if (networkRunHook(obj, NULL, NULL, if (networkRunHook(obj, NULL,
VIR_HOOK_NETWORK_OP_START, VIR_HOOK_NETWORK_OP_START,
VIR_HOOK_SUBOP_BEGIN) < 0) VIR_HOOK_SUBOP_BEGIN) < 0)
goto cleanup; goto cleanup;
@ -2821,7 +2816,7 @@ networkStartNetwork(virNetworkDriverStatePtr driver,
virNetworkObjSetFloorSum(obj, 0); virNetworkObjSetFloorSum(obj, 0);
/* finally we can call the 'started' hook script if any */ /* finally we can call the 'started' hook script if any */
if (networkRunHook(obj, NULL, NULL, if (networkRunHook(obj, NULL,
VIR_HOOK_NETWORK_OP_STARTED, VIR_HOOK_NETWORK_OP_STARTED,
VIR_HOOK_SUBOP_BEGIN) < 0) VIR_HOOK_SUBOP_BEGIN) < 0)
goto cleanup; goto cleanup;
@ -2905,7 +2900,7 @@ networkShutdownNetwork(virNetworkDriverStatePtr driver,
} }
/* now that we know it's stopped call the hook if present */ /* now that we know it's stopped call the hook if present */
networkRunHook(obj, NULL, NULL, VIR_HOOK_NETWORK_OP_STOPPED, networkRunHook(obj, NULL, VIR_HOOK_NETWORK_OP_STOPPED,
VIR_HOOK_SUBOP_END); VIR_HOOK_SUBOP_END);
virNetworkObjSetActive(obj, false); virNetworkObjSetActive(obj, false);
@ -3881,7 +3876,7 @@ networkUpdate(virNetworkPtr net,
} }
/* call the 'updated' network hook script */ /* call the 'updated' network hook script */
if (networkRunHook(obj, NULL, NULL, VIR_HOOK_NETWORK_OP_UPDATED, if (networkRunHook(obj, NULL, VIR_HOOK_NETWORK_OP_UPDATED,
VIR_HOOK_SUBOP_BEGIN) < 0) VIR_HOOK_SUBOP_BEGIN) < 0)
goto cleanup; goto cleanup;
@ -4706,8 +4701,8 @@ networkAllocateActualDevice(virNetworkPtr net,
if (dev) if (dev)
dev->connections++; dev->connections++;
/* finally we can call the 'plugged' hook script if any */ /* finally we can call the 'plugged' hook script if any */
if (networkRunHook(obj, dom, iface, if (networkRunHook(obj, port,
VIR_HOOK_NETWORK_OP_IFACE_PLUGGED, VIR_HOOK_NETWORK_OP_PORT_CREATED,
VIR_HOOK_SUBOP_BEGIN) < 0) { VIR_HOOK_SUBOP_BEGIN) < 0) {
/* adjust for failure */ /* adjust for failure */
netdef->connections--; netdef->connections--;
@ -4901,7 +4896,7 @@ networkNotifyActualDevice(virNetworkPtr net,
if (dev) if (dev)
dev->connections++; dev->connections++;
/* finally we can call the 'plugged' hook script if any */ /* finally we can call the 'plugged' hook script if any */
if (networkRunHook(obj, dom, iface, VIR_HOOK_NETWORK_OP_IFACE_PLUGGED, if (networkRunHook(obj, port, VIR_HOOK_NETWORK_OP_PORT_CREATED,
VIR_HOOK_SUBOP_BEGIN) < 0) { VIR_HOOK_SUBOP_BEGIN) < 0) {
/* adjust for failure */ /* adjust for failure */
if (dev) if (dev)
@ -5053,7 +5048,7 @@ networkReleaseActualDevice(virNetworkPtr net,
if (dev) if (dev)
dev->connections--; dev->connections--;
/* finally we can call the 'unplugged' hook script if any */ /* finally we can call the 'unplugged' hook script if any */
networkRunHook(obj, dom, iface, VIR_HOOK_NETWORK_OP_IFACE_UNPLUGGED, networkRunHook(obj, port, VIR_HOOK_NETWORK_OP_PORT_DELETED,
VIR_HOOK_SUBOP_BEGIN); VIR_HOOK_SUBOP_BEGIN);
networkLogAllocation(netdef, dev, &port->mac, false); networkLogAllocation(netdef, dev, &port->mac, false);

View File

@ -100,8 +100,8 @@ VIR_ENUM_IMPL(virHookNetworkOp,
"start", "start",
"started", "started",
"stopped", "stopped",
"plugged", "port-created",
"unplugged", "port-deleted",
"updated", "updated",
); );

View File

@ -79,8 +79,8 @@ typedef enum {
VIR_HOOK_NETWORK_OP_START, /* network is about to start */ VIR_HOOK_NETWORK_OP_START, /* network is about to start */
VIR_HOOK_NETWORK_OP_STARTED, /* network has start */ VIR_HOOK_NETWORK_OP_STARTED, /* network has start */
VIR_HOOK_NETWORK_OP_STOPPED, /* network has stopped */ VIR_HOOK_NETWORK_OP_STOPPED, /* network has stopped */
VIR_HOOK_NETWORK_OP_IFACE_PLUGGED, /* an interface has been plugged into the network */ VIR_HOOK_NETWORK_OP_PORT_CREATED, /* port has been created in the network */
VIR_HOOK_NETWORK_OP_IFACE_UNPLUGGED, /* an interface was unplugged from the network */ VIR_HOOK_NETWORK_OP_PORT_DELETED, /* port has been deleted in the network */
VIR_HOOK_NETWORK_OP_UPDATED, /* network has been updated */ VIR_HOOK_NETWORK_OP_UPDATED, /* network has been updated */
VIR_HOOK_NETWORK_OP_LAST, VIR_HOOK_NETWORK_OP_LAST,