Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
Changes | 2 +-
lib/Sys/Virt.pm | 1 +
lib/Sys/Virt.xs | 179 ++++++++++++++++++++++++++++++++++++
lib/Sys/Virt/Error.pm | 12 +++
lib/Sys/Virt/Network.pm | 39 ++++++++
lib/Sys/Virt/NetworkPort.pm | 177 +++++++++++++++++++++++++++++++++++
t/030-api-coverage.t | 2 +-
typemap | 14 +++
8 files changed, 424 insertions(+), 2 deletions(-)
create mode 100644 lib/Sys/Virt/NetworkPort.pm
diff --git a/Changes b/Changes
index 0fb13d5..e13c3b3 100644
--- a/Changes
+++ b/Changes
@@ -2,7 +2,7 @@ Revision history for perl module Sys::Virt
5.5.0 2019-07-00
- - XXX
+ - Add support for virNetworkPortPtr object and its APIs
5.4.0 2019-06-12
diff --git a/lib/Sys/Virt.pm b/lib/Sys/Virt.pm
index b6553aa..2e01fd6 100644
--- a/lib/Sys/Virt.pm
+++ b/lib/Sys/Virt.pm
@@ -69,6 +69,7 @@ use warnings;
use Sys::Virt::Error;
use Sys::Virt::Domain;
use Sys::Virt::Network;
+use Sys::Virt::NetworkPort;
use Sys::Virt::StoragePool;
use Sys::Virt::StorageVol;
use Sys::Virt::NodeDevice;
diff --git a/lib/Sys/Virt.xs b/lib/Sys/Virt.xs
index 9586be8..ccd5ba0 100644
--- a/lib/Sys/Virt.xs
+++ b/lib/Sys/Virt.xs
@@ -6828,6 +6828,27 @@ PREINIT:
free(leases);
+void
+list_all_ports(net, flags=0)
+ virNetworkPtr net;
+ unsigned int flags;
+ PREINIT:
+ virNetworkPortPtr *ports;
+ int i, nport;
+ SV *portrv;
+ PPCODE:
+ if ((nport = virNetworkListAllPorts(net, &ports, flags)) < 0)
+ _croak_error();
+
+ EXTEND(SP, nport);
+ for (i = 0 ; i < nport ; i++) {
+ portrv = sv_newmortal();
+ sv_setref_pv(portrv, "Sys::Virt::NetworkPort", ports[i]);
+ PUSHs(portrv);
+ }
+ free(ports);
+
+
void
destroy(net_rv)
SV *net_rv;
@@ -6852,6 +6873,150 @@ DESTROY(net_rv)
}
+MODULE = Sys::Virt::NetworkPort PACKAGE = Sys::Virt::NetworkPort
+
+
+virNetworkPortPtr
+_create_xml(net, xml, flags=0)
+ virNetworkPtr net;
+ const char *xml;
+ unsigned int flags;
+ CODE:
+ if (!(RETVAL = virNetworkPortCreateXML(net, xml, flags)))
+ _croak_error();
+ OUTPUT:
+ RETVAL
+
+
+virNetworkPortPtr
+_lookup_by_uuid(net, uuid)
+ virNetworkPtr net;
+ const unsigned char *uuid;
+ CODE:
+ if (!(RETVAL = virNetworkPortLookupByUUID(net, uuid)))
+ _croak_error();
+ OUTPUT:
+ RETVAL
+
+
+virNetworkPortPtr
+_lookup_by_uuid_string(net, uuid)
+ virNetworkPtr net;
+ const char *uuid;
+ CODE:
+ if (!(RETVAL = virNetworkPortLookupByUUIDString(net, uuid)))
+ _croak_error();
+
+ OUTPUT:
+ RETVAL
+
+
+SV *
+get_uuid(port)
+ virNetworkPortPtr port;
+ PREINIT:
+ unsigned char rawuuid[VIR_UUID_BUFLEN];
+ CODE:
+ if ((virNetworkPortGetUUID(port, rawuuid)) < 0)
+ _croak_error();
+
+ RETVAL = newSVpv((char*)rawuuid, sizeof(rawuuid));
+ OUTPUT:
+ RETVAL
+
+
+SV *
+get_uuid_string(port)
+ virNetworkPortPtr port;
+ PREINIT:
+ char uuid[VIR_UUID_STRING_BUFLEN];
+ CODE:
+ if ((virNetworkPortGetUUIDString(port, uuid)) < 0)
+ _croak_error();
+
+ RETVAL = newSVpv(uuid, 0);
+ OUTPUT:
+ RETVAL
+
+
+SV *
+get_xml_description(port, flags=0)
+ virNetworkPortPtr port;
+ unsigned int flags;
+ PREINIT:
+ char *xml;
+ CODE:
+ if (!(xml = virNetworkPortGetXMLDesc(port, flags)))
+ _croak_error();
+
+ RETVAL = newSVpv(xml, 0);
+ free(xml);
+ OUTPUT:
+ RETVAL
+
+
+HV *
+get_parameters(port, flags=0)
+ virNetworkPortPtr port;
+ unsigned int flags;
+ PREINIT:
+ virTypedParameterPtr params = NULL;
+ int nparams = 0;
+ CODE:
+ if (virNetworkPortGetParameters(port, ¶ms, &nparams, flags) < 0) {
+ vir_typed_param_safe_free(params, nparams);
+ _croak_error();
+ }
+
+ RETVAL = vir_typed_param_to_hv(params, nparams);
+ vir_typed_param_safe_free(params, nparams);
+ OUTPUT:
+ RETVAL
+
+
+void
+set_parameters(port, newparams, flags=0)
+ virNetworkPortPtr port;
+ HV *newparams;
+ unsigned int flags;
+ PREINIT:
+ virTypedParameterPtr params = NULL;
+ int nparams = 0;
+ PPCODE:
+ if (virNetworkPortGetParameters(port, ¶ms, &nparams, 0) < 0) {
+ vir_typed_param_safe_free(params, nparams);
+ _croak_error();
+ }
+
+ nparams = vir_typed_param_from_hv(newparams, params, nparams);
+
+ if (virNetworkPortSetParameters(port, params, nparams, flags) < 0)
+ _croak_error();
+ vir_typed_param_safe_free(params, nparams);
+
+
+void
+delete(port, flags=0)
+ virNetworkPortPtr port;
+ unsigned int flags;
+ PPCODE:
+ if (virNetworkPortDelete(port, flags) < 0)
+ _croak_error();
+
+
+void
+DESTROY(port_rv)
+ SV *port_rv;
+ PREINIT:
+ virNetworkPortPtr port;
+ PPCODE:
+ port = (virNetworkPortPtr)SvIV((SV*)SvRV(port_rv));
+ if (port) {
+ virNetworkPortFree(port);
+ sv_setiv((SV*)SvRV(port_rv), 0);
+ }
+
+
MODULE = Sys::Virt::StoragePool PACKAGE = Sys::Virt::StoragePool
@@ -9577,6 +9742,17 @@ BOOT:
REGISTER_CONSTANT(VIR_NETWORK_EVENT_STOPPED, EVENT_STOPPED);
+ stash = gv_stashpv( "Sys::Virt::NetworkPort", TRUE );
+ REGISTER_CONSTANT(VIR_NETWORK_PORT_CREATE_RECLAIM, CREATE_RECLAIM);
+
+ REGISTER_CONSTANT_STR(VIR_NETWORK_PORT_BANDWIDTH_IN_AVERAGE,
BANDWIDTH_IN_AVERAGE);
+ REGISTER_CONSTANT_STR(VIR_NETWORK_PORT_BANDWIDTH_IN_BURST, BANDWIDTH_IN_BURST);
+ REGISTER_CONSTANT_STR(VIR_NETWORK_PORT_BANDWIDTH_IN_FLOOR, BANDWIDTH_IN_FLOOR);
+ REGISTER_CONSTANT_STR(VIR_NETWORK_PORT_BANDWIDTH_IN_PEAK, BANDWIDTH_IN_PEAK);
+ REGISTER_CONSTANT_STR(VIR_NETWORK_PORT_BANDWIDTH_OUT_AVERAGE,
BANDWIDTH_OUT_AVERAGE);
+ REGISTER_CONSTANT_STR(VIR_NETWORK_PORT_BANDWIDTH_OUT_BURST, BANDWIDTH_OUT_BURST);
+ REGISTER_CONSTANT_STR(VIR_NETWORK_PORT_BANDWIDTH_OUT_PEAK, BANDWIDTH_OUT_PEAK);
+
stash = gv_stashpv( "Sys::Virt::Interface", TRUE );
REGISTER_CONSTANT(VIR_INTERFACE_XML_INACTIVE, XML_INACTIVE);
@@ -9863,4 +10039,7 @@ BOOT:
REGISTER_CONSTANT(VIR_ERR_INVALID_DOMAIN_CHECKPOINT,
ERR_INVALID_DOMAIN_CHECKPOINT);
REGISTER_CONSTANT(VIR_ERR_NO_DOMAIN_BACKUP, ERR_NO_DOMAIN_BACKUP);
REGISTER_CONSTANT(VIR_ERR_NO_DOMAIN_CHECKPOINT, ERR_NO_DOMAIN_CHECKPOINT);
+ REGISTER_CONSTANT(VIR_ERR_NO_NETWORK_PORT, ERR_NO_NETWORK_PORT);
+ REGISTER_CONSTANT(VIR_ERR_INVALID_NETWORK_PORT, ERR_INVALID_NETWORK_PORT);
+ REGISTER_CONSTANT(VIR_ERR_NETWORK_PORT_EXIST, ERR_NETWORK_PORT_EXIST);
}
diff --git a/lib/Sys/Virt/Error.pm b/lib/Sys/Virt/Error.pm
index d65ceb5..3f48769 100644
--- a/lib/Sys/Virt/Error.pm
+++ b/lib/Sys/Virt/Error.pm
@@ -844,6 +844,18 @@ Domain checkpoint not found
Domain backup job id not found
+=item Sys::Virt::Error::ERR_NO_NETWORK_PORT
+
+No matching network port
+
+=item Sys::Virt::Error::ERR_INVALID_NETWORK_PORT
+
+Invalid network port object
+
+=item Sys::Virt::Error::ERR_NETWORK_PORT_EXIST
+
+Network port already exists
+
=back
=head1 AUTHORS
diff --git a/lib/Sys/Virt/Network.pm b/lib/Sys/Virt/Network.pm
index 415e629..e4b54da 100644
--- a/lib/Sys/Virt/Network.pm
+++ b/lib/Sys/Virt/Network.pm
@@ -193,6 +193,45 @@ The client ID or DUID
=back
+=item @port = $net->list_all_ports($flags=0)
+
+List all ports associated with the network. The return array elements
+are instances of the C<Sys::Virt::NetworkPort> class.
+
+=item $port = $net->create_port($xml, $flags=0)
+
+Create a new network port from the given C<$xml> description. The C<$flags>
+parameter can optionally taken one or more of the network port creation
+constants. The returned C<$port> object is an instance of the
+C<Sys::Virt::NetworkPort> class.
+
+=cut
+
+sub create_port {
+ my $self = shift;
+ my $xml = shift;
+ my $flags = shift || 0;
+
+ return Sys::Virt::NetworkPort->_new(net => $self, xml => $xml, flags =>
$flags);
+}
+
+
+=item $port = $net->get_port_by_uuid($uuid);
+
+Lookup a network port from a raw or printable UUID.
+The returned C<$port> object is an instance of the C<Sys::Virt::NetworkPort>
+class.
+
+=cut
+
+sub get_port_by_uuid {
+ my $self = shift;
+ my $uuid = shift;
+
+ return Sys::Virt::NetworkPort->_new(net => $self, uuid => $uuid);
+}
+
+
=back
=head1 CONSTANTS
diff --git a/lib/Sys/Virt/NetworkPort.pm b/lib/Sys/Virt/NetworkPort.pm
new file mode 100644
index 0000000..9e9bf37
--- /dev/null
+++ b/lib/Sys/Virt/NetworkPort.pm
@@ -0,0 +1,177 @@
+# -*- perl -*-
+#
+# Copyright (C) 2019 Red Hat
+#
+# This program is free software; You can redistribute it and/or modify
+# it under either:
+#
+# a) the GNU General Public License as published by the Free
+# Software Foundation; either version 2, or (at your option) any
+# later version,
+#
+# or
+#
+# b) the "Artistic License"
+#
+# The file "LICENSE" distributed along with this file provides full
+# details of the terms and conditions of the two licenses.
+
+=pod
+
+=head1 NAME
+
+Sys::Virt::NetworkPort - Represent & manage a libvirt virtual network port
+
+=head1 DESCRIPTION
+
+The C<Sys::Virt::NetworkPort> module represents a port in a virtual network.
+
+=head1 METHODS
+
+=over 4
+
+=cut
+
+package Sys::Virt::NetworkPort;
+
+use strict;
+use warnings;
+
+
+sub _new {
+ my $proto = shift;
+ my $class = ref($proto) || $proto;
+ my %params = @_;
+
+ my $net = exists $params{network} ? $params{network} : die "network parameter is
required";
+ my $self;
+ if (exists $params{uuid}) {
+ if (length($params{uuid}) == 16) {
+ $self = Sys::Virt::NetworkPort::_lookup_by_uuid($net, $params{uuid});
+ } elsif (length($params{uuid}) == 32 ||
+ length($params{uuid}) == 36) {
+ $self = Sys::Virt::NetworkPort::_lookup_by_uuid_string($net, $params{uuid});
+ } else {
+ die "UUID must be either 16 unsigned bytes, or 32/36 hex characters
long";
+ }
+ } elsif (exists $params{xml}) {
+ my $flags = $params{flags} || 0;
+ $self = Sys::Virt::NetworkPort::_create_xml($net, $params{xml}, $flags);
+ } else {
+ die "uuid or xml parameters are required";
+ }
+
+ bless $self, $class;
+
+ return $self;
+}
+
+
+=item my $uuid = $net->get_uuid()
+
+Returns a 16 byte long string containing the raw globally unique identifier
+(UUID) for the network port.
+
+=item my $uuid = $net->get_uuid_string()
+
+Returns a printable string representation of the raw UUID, in the format
+'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'.
+
+=item my $xml = $net->get_xml_description()
+
+Returns an XML document containing a complete description of
+the network port's configuration
+
+=item $net->delete()
+
+Delete the network port from the managed network.
+
+=item my $params = $net->get_parameters($flags=0);
+
+Get tunable parameters associated with the network port. The C<$flags>
+parameter is currently unused and defaults to zero. The returned
+C<$params> is a hash reference whose keys are one or more of the
+following constants:
+
+=over 4
+
+=item Sys::Virt::NetworkPort::BANDWIDTH_IN_AVERAGE
+
+The average inbound bandwidth
+
+=item Sys::Virt::NetworkPort::BANDWIDTH_IN_BURST
+
+The burstable inbound bandwidth
+
+=item Sys::Virt::NetworkPort::BANDWIDTH_IN_FLOOR
+
+The minimum inbound bandwidth
+
+=item Sys::Virt::NetworkPort::BANDWIDTH_IN_PEAK
+
+The peak inbound bandwidth
+
+=item Sys::Virt::NetworkPort::BANDWIDTH_OUT_AVERAGE
+
+The average outbound bandwidth
+
+=item Sys::Virt::NetworkPort::BANDWIDTH_OUT_BURST
+
+The burstable outbound bandwidth
+
+=item Sys::Virt::NetworkPort::BANDWIDTH_OUT_PEAK
+
+The peak outbound bandwidth
+
+=back
+
+=item $net->set_parameters($params, $flags=0);
+
+Set tunable parameters associated with the network port. The C<$flags>
+parameter is currently unused and defaults to zero. The C<$params>
+parameter is a hash reference whose keys are one or more of the
+constants listed for C<get_parameters>.
+
+=back
+
+=head2 NETWORK PORT CREATION CONSTANTS
+
+When creating network ports zero or more of the following
+constants may be used
+
+=over 4
+
+=item Sys::Virt::NetworkPort::CREATE_RECLAIM
+
+Providing configuration reclaiming a pre-existing network port.
+
+=back
+
+
+=cut
+
+
+1;
+
+
+=head1 AUTHORS
+
+Daniel P. Berrange <berrange(a)redhat.com>
+
+=head1 COPYRIGHT
+
+Copyright (C) 2019 Red Hat
+
+=head1 LICENSE
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of either the GNU General Public License as published
+by the Free Software Foundation (either version 2 of the License, or at
+your option any later version), or, the Artistic License, as specified
+in the Perl README file.
+
+=head1 SEE ALSO
+
+L<Sys::Virt>, L<Sys::Virt::Network>, L<Sys::Virt::Error>,
C<http://libvirt.org>
+
+=cut
diff --git a/t/030-api-coverage.t b/t/030-api-coverage.t
index 15d4a77..0b6592a 100644
--- a/t/030-api-coverage.t
+++ b/t/030-api-coverage.t
@@ -152,7 +152,7 @@ virNetworkDHCPLeaseFree
);
foreach my $func (sort { $a cmp $b } @functions) {
- if ($func =~ /(GetConnect|Ref|GetDomain)$/ ||
+ if ($func =~ /(GetConnect|Ref|GetDomain|GetNetwork)$/ ||
grep {/$func/ } @blacklist) {
ok(1, $func);
next;
diff --git a/typemap b/typemap
index 9784094..b316aa2 100644
--- a/typemap
+++ b/typemap
@@ -4,6 +4,7 @@ const unsigned char * T_PV
virConnectPtr O_OBJECT_connect
virDomainPtr O_OBJECT_domain
virNetworkPtr O_OBJECT_network
+virNetworkPortPtr O_OBJECT_network_port
virNWFilterPtr O_OBJECT_nwfilter
virNWFilterBindingPtr O_OBJECT_nwfilter_binding
virInterfacePtr O_OBJECT_interface
@@ -55,6 +56,19 @@ OUTPUT
O_OBJECT_network
sv_setref_pv( $arg, "Sys::Virt::Network", (void*)$var );
+INPUT
+O_OBJECT_network_port
+ if (sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG))
+ $var = INT2PTR($type, SvIV((SV*)SvRV( $arg )));
+ else {
+ warn( \"${Package}::$func_name() -- $var is not a blessed SV
reference\" );
+ XSRETURN_UNDEF;
+ }
+
+OUTPUT
+O_OBJECT_network_port
+ sv_setref_pv( $arg, "Sys::Virt::NetworkPort", (void*)$var );
+
INPUT
O_OBJECT_storagepool
--
2.21.0