On 09/20/2012 12:55 PM, Eric Blake wrote:
On 09/20/2012 09:05 AM, Laine Stump wrote:
> This new virsh command uses the new virNetworkUpdate() API to modify
> an existing network definition, and optionally have those
> modifications take effect immediately without restarting the network.
>
> An example usage:
>
> virsh net-update mynet add-last ip-dhcp-host \
> "<host mac='00:11:22:33:44:55'
ip='192.168.122.45'/>" \
> --live --config
>
> If you like, you can instead put the xml into a file, and call like
> this:
>
> virsh net-update mynet add ip-dhcp-host /tmp/myxml.xml
> --live --config
>
> (since an xml element must always start with "<", but a filename
> rarely does, virsh just checks the first character of the supplied
> "--xml" argument, and decides whether to use the text directly or as a
> filename. In the rare event that someone really does have a filename
> starting with "<", they can specify it as "./<xxxx".)
I like this version the best.
> + * "net-update" command
> + */
> +static const vshCmdInfo info_network_update[] = {
> + {"help", N_("update parts of an existing network's
configuration")},
> + {"desc", ""},
> + {NULL, NULL}
> +};
> +
> +static const vshCmdOptDef opts_network_update[] = {
> + {"network", VSH_OT_DATA, VSH_OFLAG_REQ, N_("network name or
uuid")},
> + {"command", VSH_OT_DATA, VSH_OFLAG_REQ,
> + N_("type of update (add-first, add-last (add), delete, or
modify)")},
> + {"section", VSH_OT_DATA, VSH_OFLAG_REQ,
> + N_("which section of network configuration to update")},
> + {"xml", VSH_OT_DATA, VSH_OFLAG_REQ,
> + N_("name of file containing xml (or, if it starts with '<', the
complete "
> + "xml element itself) to add/modify, or to be matched for
search")},
Two spaces after ')' looks fishy.
> +
> + /* The goal is to have a full xml element in the "xml"
> + * string. This is provided in the --xml option, either directly
> + * (detected by the first character being "<"), or indirectly by
> + * supplying a filename (first character isn't "<") that
contains
> + * the desired xml.
> + */
> +
> + if (vshCommandOptString(cmd, "xml", &xml) < 0) {
> + vshError(ctl, "%s", _("malformed or missing xml
argument"));
> + goto cleanup;
> + }
> +
> + if (*xml != '<') {
> + /* contents of xmldata is actually the name of a file that
> + * contains the xml.
> + */
> + if (virFileReadAll(xml, VSH_MAX_XML_FILE, &xmlFromFile) < 0)
> + return false;
> + /* NB: the original xml is just a const char * that points
> + * to a string owned by the Command object, and will be freed
> + * by vshCommandFree. so it's safe to lose its pointer here.
> + */
> + xml = xmlFromFile;
> + }
> +
> + if (current) {
> + if (live || config) {
> + vshError(ctl, "%s", _("--current must be specified
exclusively"));
> + return false;
> + }
> + flags |= VIR_NETWORK_UPDATE_AFFECT_CURRENT;
> + } else {
> + if (config)
> + flags |= VIR_NETWORK_UPDATE_AFFECT_CONFIG;
> + if (live)
> + flags |= VIR_NETWORK_UPDATE_AFFECT_LIVE;
> + }
> +
> + if (virNetworkUpdate(network, command,
> + section, parentIndex, xml, flags) < 0) {
> + vshError(ctl, _("Failed to update network %s"),
> + virNetworkGetName(network));
> + goto cleanup;
> + }
> +
> + if (flags & VIR_NETWORK_UPDATE_AFFECT_CONFIG) {
If you want, this could be simplified to: 'if (config) {'
> + if (flags & VIR_NETWORK_UPDATE_AFFECT_LIVE)
> + affected = _("persistent config and live state");
> + else
> + affected = _("persistent config");
> + } else if (flags & VIR_NETWORK_UPDATE_AFFECT_LIVE) {
and likewise simplify these two bitwise ops to 'if (live)'.
ACK (unless I get outvoted by other opinions :).
In the interest of getting maximum testing, I'm pushing this version
(fixed up as you suggested, and also adding another fix to avoid leaking
a virNetwork object when the requested file doesn't exist). If this
method is successful for net-update, it can possibly be added to the
other commands that take a file-containing-xml option (the only
difference between the commands is in the name of that option, and that
name is usually unspecified in commandlines anyway).