[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Added network.other_config map. To make this easier, add a new automatic



# HG changeset patch
# User Ewan Mellor <ewan@xxxxxxxxxxxxx>
# Date 1174951160 -3600
# Node ID 03d0dda70a8f0bc592af99b43b10e8dde77c7a85
# Parent  616611521a1deeb0ac927f53531fc5b7a7fa7843
Added network.other_config map.  To make this easier, add a new automatic
plumbing facility from the XendNetwork class into XendAPI (credit to Tom
Wilkie for the idea).

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>
---
 docs/xen-api/xenapi-datamodel.tex       |  140 ++++++++++++++++++++++++++++++++
 tools/libxen/include/xen_network.h      |   33 +++++++
 tools/libxen/src/xen_network.c          |   74 ++++++++++++++++
 tools/python/xen/xend/XendAPI.py        |   91 ++++++++++++--------
 tools/python/xen/xend/XendNetwork.py    |   43 ++++++++-
 tools/python/xen/xend/XendNode.py       |   14 +--
 tools/python/xen/xend/XendStateStore.py |   13 ++
 7 files changed, 354 insertions(+), 54 deletions(-)

diff -r 616611521a1d -r 03d0dda70a8f docs/xen-api/xenapi-datamodel.tex
--- a/docs/xen-api/xenapi-datamodel.tex Tue Mar 27 00:15:07 2007 +0100
+++ b/docs/xen-api/xenapi-datamodel.tex Tue Mar 27 00:19:20 2007 +0100
@@ -6549,6 +6549,7 @@ Quals & Field & Type & Description \\
 $\mathit{RW}$ &  {\tt name/description} & string & a notes field containg 
human-readable description \\
 $\mathit{RO}_\mathit{run}$ &  {\tt VIFs} & (VIF ref) Set & list of connected 
vifs \\
 $\mathit{RO}_\mathit{run}$ &  {\tt PIFs} & (PIF ref) Set & list of connected 
pifs \\
+$\mathit{RW}$ &  {\tt other\_config} & (string $\rightarrow$ string) Map & 
additional configuration \\
 \hline
 \end{longtable}
 \subsection{RPCs associated with class: network}
@@ -6798,6 +6799,145 @@ Get the PIFs field of the given network.
 
 
 value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_other\_config}
+
+{\bf Overview:} 
+Get the other\_config field of the given network.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} ((string -> string) Map) get_other_config (session_id s, 
network ref self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt network ref } & self & reference to the object \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+(string $\rightarrow$ string) Map
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~set\_other\_config}
+
+{\bf Overview:} 
+Set the other\_config field of the given network.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} void set_other_config (session_id s, network ref self, 
(string -> string) Map value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt network ref } & self & reference to the object \\ \hline 
+
+{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~add\_to\_other\_config}
+
+{\bf Overview:} 
+Add the given key-value pair to the other\_config field of the given
+network.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} void add_to_other_config (session_id s, network ref self, 
string key, string value)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt network ref } & self & reference to the object \\ \hline 
+
+{\tt string } & key & Key to add \\ \hline 
+
+{\tt string } & value & Value to add \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~remove\_from\_other\_config}
+
+{\bf Overview:} 
+Remove the given key and its corresponding value from the other\_config
+field of the given network.  If the key is not in that Map, then do
+nothing.
+
+ \noindent {\bf Signature:} 
+\begin{verbatim} void remove_from_other_config (session_id s, network ref 
self, string key)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+ 
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt network ref } & self & reference to the object \\ \hline 
+
+{\tt string } & key & Key to remove \\ \hline 
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:} 
+{\tt 
+void
+}
+
+
+
 \vspace{0.3cm}
 \vspace{0.3cm}
 \vspace{0.3cm}
diff -r 616611521a1d -r 03d0dda70a8f tools/libxen/include/xen_network.h
--- a/tools/libxen/include/xen_network.h        Tue Mar 27 00:15:07 2007 +0100
+++ b/tools/libxen/include/xen_network.h        Tue Mar 27 00:19:20 2007 +0100
@@ -22,6 +22,7 @@
 #include "xen_common.h"
 #include "xen_network_decl.h"
 #include "xen_pif_decl.h"
+#include "xen_string_string_map.h"
 #include "xen_vif_decl.h"
 
 
@@ -68,6 +69,7 @@ typedef struct xen_network_record
     char *name_description;
     struct xen_vif_record_opt_set *vifs;
     struct xen_pif_record_opt_set *pifs;
+    xen_string_string_map *other_config;
 } xen_network_record;
 
 /**
@@ -220,6 +222,13 @@ xen_network_get_pifs(xen_session *sessio
 
 
 /**
+ * Get the other_config field of the given network.
+ */
+extern bool
+xen_network_get_other_config(xen_session *session, xen_string_string_map 
**result, xen_network network);
+
+
+/**
  * Set the name/label field of the given network.
  */
 extern bool
@@ -234,6 +243,30 @@ xen_network_set_name_description(xen_ses
 
 
 /**
+ * Set the other_config field of the given network.
+ */
+extern bool
+xen_network_set_other_config(xen_session *session, xen_network network, 
xen_string_string_map *other_config);
+
+
+/**
+ * Add the given key-value pair to the other_config field of the given
+ * network.
+ */
+extern bool
+xen_network_add_to_other_config(xen_session *session, xen_network network, 
char *key, char *value);
+
+
+/**
+ * Remove the given key and its corresponding value from the
+ * other_config field of the given network.  If the key is not in that Map,
+ * then do nothing.
+ */
+extern bool
+xen_network_remove_from_other_config(xen_session *session, xen_network 
network, char *key);
+
+
+/**
  * Return a list of all the networks known to the system.
  */
 extern bool
diff -r 616611521a1d -r 03d0dda70a8f tools/libxen/src/xen_network.c
--- a/tools/libxen/src/xen_network.c    Tue Mar 27 00:15:07 2007 +0100
+++ b/tools/libxen/src/xen_network.c    Tue Mar 27 00:19:20 2007 +0100
@@ -24,6 +24,7 @@
 #include "xen_internal.h"
 #include "xen_network.h"
 #include "xen_pif.h"
+#include "xen_string_string_map.h"
 #include "xen_vif.h"
 
 
@@ -52,7 +53,10 @@ static const struct_member xen_network_r
           .offset = offsetof(xen_network_record, vifs) },
         { .key = "PIFs",
           .type = &abstract_type_ref_set,
-          .offset = offsetof(xen_network_record, pifs) }
+          .offset = offsetof(xen_network_record, pifs) },
+        { .key = "other_config",
+          .type = &abstract_type_string_string_map,
+          .offset = offsetof(xen_network_record, other_config) }
     };
 
 const abstract_type xen_network_record_abstract_type_ =
@@ -78,6 +82,7 @@ xen_network_record_free(xen_network_reco
     free(record->name_description);
     xen_vif_record_opt_set_free(record->vifs);
     xen_pif_record_opt_set_free(record->pifs);
+    xen_string_string_map_free(record->other_config);
     free(record);
 }
 
@@ -239,6 +244,23 @@ xen_network_get_pifs(xen_session *sessio
 
 
 bool
+xen_network_get_other_config(xen_session *session, xen_string_string_map 
**result, xen_network network)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = network }
+        };
+
+    abstract_type result_type = abstract_type_string_string_map;
+
+    *result = NULL;
+    XEN_CALL_("network.get_other_config");
+    return session->ok;
+}
+
+
+bool
 xen_network_set_name_label(xen_session *session, xen_network network, char 
*label)
 {
     abstract_value param_values[] =
@@ -271,6 +293,56 @@ xen_network_set_name_description(xen_ses
 
 
 bool
+xen_network_set_other_config(xen_session *session, xen_network network, 
xen_string_string_map *other_config)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = network },
+            { .type = &abstract_type_string_string_map,
+              .u.set_val = (arbitrary_set *)other_config }
+        };
+
+    xen_call_(session, "network.set_other_config", param_values, 2, NULL, 
NULL);
+    return session->ok;
+}
+
+
+bool
+xen_network_add_to_other_config(xen_session *session, xen_network network, 
char *key, char *value)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = network },
+            { .type = &abstract_type_string,
+              .u.string_val = key },
+            { .type = &abstract_type_string,
+              .u.string_val = value }
+        };
+
+    xen_call_(session, "network.add_to_other_config", param_values, 3, NULL, 
NULL);
+    return session->ok;
+}
+
+
+bool
+xen_network_remove_from_other_config(xen_session *session, xen_network 
network, char *key)
+{
+    abstract_value param_values[] =
+        {
+            { .type = &abstract_type_string,
+              .u.string_val = network },
+            { .type = &abstract_type_string,
+              .u.string_val = key }
+        };
+
+    xen_call_(session, "network.remove_from_other_config", param_values, 2, 
NULL, NULL);
+    return session->ok;
+}
+
+
+bool
 xen_network_get_all(xen_session *session, struct xen_network_set **result)
 {
 
diff -r 616611521a1d -r 03d0dda70a8f tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py  Tue Mar 27 00:15:07 2007 +0100
+++ b/tools/python/xen/xend/XendAPI.py  Tue Mar 27 00:19:20 2007 +0100
@@ -32,6 +32,7 @@ from xen.xend.XendError import *
 from xen.xend.XendError import *
 from xen.xend.XendClient import ERROR_INVALID_DOMAIN
 from xen.xend.XendLogging import log
+from xen.xend.XendNetwork import XendNetwork
 from xen.xend.XendTask import XendTask
 from xen.xend.XendVMMetrics import XendVMMetrics
 
@@ -436,6 +437,10 @@ class XendAPI(object):
             'debug'        : valid_debug,
         }
 
+        autoplug_classes = {
+            'network' : XendNetwork
+        }
+
         # Cheat methods
         # -------------
         # Methods that have a trivial implementation for all classes.
@@ -457,6 +462,41 @@ class XendAPI(object):
             setattr(cls, get_by_uuid, _get_by_uuid)
             setattr(cls, get_uuid,    _get_uuid)
 
+
+        # Autoplugging classes
+        # --------------------
+        # These have all of their methods grabbed out from the implementation
+        # class, and wrapped up to be compatible with the Xen-API.
+        
+        for api_cls, impl_cls in autoplug_classes.items():
+            getter = getattr(cls, '_%s_get' % api_cls)
+
+            def doit(n):
+                dot_n = '%s.%s' % (api_cls, n)
+                full_n = '%s_%s' % (api_cls, n)
+                if not hasattr(cls, full_n):
+                    f = getattr(impl_cls, n)
+                    argcounts[dot_n] = f.func_code.co_argcount + 1
+                    setattr(cls, full_n,
+                            lambda s, session, ref, *args: \
+                               xen_api_success( \
+                                   f(getter(s, session, ref), *args)))
+
+            ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
+            rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
+            methods  = getattr(cls, '%s_methods' % api_cls, [])
+            funcs    = getattr(cls, '%s_funcs'   % api_cls, [])
+            
+            for attr_name in ro_attrs + rw_attrs:
+                doit('get_%s' % attr_name)
+            for attr_name in rw_attrs + cls.Base_attr_rw:
+                doit('set_%s' % attr_name)
+            for method_name, return_type in methods + cls.Base_methods:
+                doit('%s' % method_name)
+            for func_name, return_type in funcs + cls.Base_funcs:
+                doit('%s' % func_name)
+
+
         # Wrapping validators around XMLRPC calls
         # ---------------------------------------
 
@@ -466,7 +506,8 @@ class XendAPI(object):
                 n_ = n.replace('.', '_')
                 try:
                     f = getattr(cls, n_)
-                    argcounts[n] = f.func_code.co_argcount - 1
+                    if n not in argcounts:
+                        argcounts[n] = f.func_code.co_argcount - 1
                     
                     validators = takes_instance and validator and \
                                  [validator] or []
@@ -916,44 +957,24 @@ class XendAPI(object):
 
     network_attr_ro = ['VIFs', 'PIFs']
     network_attr_rw = ['name_label',
-                       'name_description']
-    
-    network_funcs = [('create', 'network')]
-    
-    def network_create(self, _, name_label, name_description):
-        return xen_api_success(
-            XendNode.instance().network_create(name_label, name_description))
+                       'name_description',
+                       'other_config']
+    network_methods = [('add_to_other_config', None),
+                       ('remove_from_other_config', None)]
+    network_funcs = [('create', None)]
+    
+    def _network_get(self, _, ref):
+        return XendNode.instance().get_network(ref)
+
+    def network_get_all(self, _):
+        return xen_api_success(XendNode.instance().get_network_refs())
+
+    def network_create(self, _, record):
+        return xen_api_success(XendNode.instance().network_create(record))
 
     def network_destroy(self, _, ref):
         return xen_api_success(XendNode.instance().network_destroy(ref))
 
-    def _get_network(self, ref):
-        return XendNode.instance().get_network(ref)
-
-    def network_get_all(self, _):
-        return xen_api_success(XendNode.instance().get_network_refs())
-
-    def network_get_record(self, _, ref):
-        return xen_api_success(
-            XendNode.instance().get_network(ref).get_record())
-
-    def network_get_name_label(self, _, ref):
-        return xen_api_success(self._get_network(ref).name_label)
-
-    def network_get_name_description(self, _, ref):
-        return xen_api_success(self._get_network(ref).name_description)
-
-    def network_get_VIFs(self, _, ref):
-        return xen_api_success(self._get_network(ref).get_VIF_UUIDs())
-
-    def network_get_PIFs(self, session, ref):
-        return xen_api_success(self._get_network(ref).get_PIF_UUIDs())
-
-    def network_set_name_label(self, _, ref, val):
-        return xen_api_success(self._get_network(ref).set_name_label(val))
-
-    def network_set_name_description(self, _, ref, val):
-        return 
xen_api_success(self._get_network(ref).set_name_description(val))
 
     # Xen API: Class PIF
     # ----------------------------------------------------------------
diff -r 616611521a1d -r 03d0dda70a8f tools/python/xen/xend/XendNetwork.py
--- a/tools/python/xen/xend/XendNetwork.py      Tue Mar 27 00:15:07 2007 +0100
+++ b/tools/python/xen/xend/XendNetwork.py      Tue Mar 27 00:19:20 2007 +0100
@@ -28,10 +28,17 @@ IP_ROUTE_RE = r'^default via ([\d\.]+) d
 IP_ROUTE_RE = r'^default via ([\d\.]+) dev (\w+)'
 
 class XendNetwork:
-    def __init__(self, uuid, name, description):
+    def __init__(self, uuid, record):
         self.uuid = uuid
-        self.name_label = name 
-        self.name_description = description
+        self.name_label = record.get('name_label', '')
+        self.name_description = record.get('name_description', '')
+        self.other_config = record.get('other_config', {})
+
+    def get_name_label(self):
+        return self.name_label
+
+    def get_name_description(self):
+        return self.name_description
 
     def set_name_label(self, new_name):
         self.name_label = new_name
@@ -41,7 +48,7 @@ class XendNetwork:
         self.name_description = new_desc
         XendNode.instance().save_networks()
 
-    def get_VIF_UUIDs(self):
+    def get_VIFs(self):
         result = []
         vms = XendDomain.instance().get_all_vms()
         for vm in vms:
@@ -52,17 +59,37 @@ class XendNetwork:
                     result.append(vif)
         return result
 
-    def get_PIF_UUIDs(self):
+    def get_PIFs(self):
         return [x.uuid for x in XendNode.instance().pifs.values()
                 if x.network == self]
 
-    def get_record(self, transient = True):
+    def get_other_config(self):
+        return self.other_config
+
+    def set_other_config(self, value):
+        self.other_config = value
+        XendNode.instance().save_networks()
+
+    def add_to_other_config(self, key, value):
+        self.other_config[key] = value
+        XendNode.instance().save_networks()
+
+    def remove_from_other_config(self, key):
+        if key in self.other_config:
+            del self.other_config[key]
+        XendNode.instance().save_networks()
+
+    def get_record(self):
+        return self.get_record_internal(True)
+
+    def get_record_internal(self, transient):
         result = {
             'uuid': self.uuid,
             'name_label': self.name_label,
             'name_description': self.name_description,
+            'other_config' : self.other_config,
         }
         if transient:
-            result['VIFs'] = self.get_VIF_UUIDs()
-            result['PIFs'] = self.get_PIF_UUIDs()
+            result['VIFs'] = self.get_VIFs()
+            result['PIFs'] = self.get_PIFs()
         return result
diff -r 616611521a1d -r 03d0dda70a8f tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Tue Mar 27 00:15:07 2007 +0100
+++ b/tools/python/xen/xend/XendNode.py Tue Mar 27 00:19:20 2007 +0100
@@ -141,11 +141,9 @@ class XendNode:
         saved_networks = self.state_store.load_state('network')
         if saved_networks:
             for net_uuid, network in saved_networks.items():
-                self.network_create(network.get('name_label'),
-                                    network.get('name_description', ''),
-                                    False, net_uuid)
+                self.network_create(network, False, net_uuid)
         else:
-            self.network_create('net0', '', False)
+            self.network_create({'name_label' : 'net0' }, False)
 
         # initialise PIFs
         saved_pifs = self.state_store.load_state('pif')
@@ -199,12 +197,10 @@ class XendNode:
 
 
 
-    def network_create(self, name_label, name_description, persist = True,
-                       net_uuid = None):
+    def network_create(self, record, persist = True, net_uuid = None):
         if net_uuid is None:
             net_uuid = uuid.createString()
-        self.networks[net_uuid] = XendNetwork(net_uuid, name_label,
-                                              name_description)
+        self.networks[net_uuid] = XendNetwork(net_uuid, record)
         if persist:
             self.save_networks()
         return net_uuid
@@ -280,7 +276,7 @@ class XendNode:
         self.state_store.save_state('pif', pif_records)
 
     def save_networks(self):
-        net_records = dict([(k, v.get_record(transient = False))
+        net_records = dict([(k, v.get_record_internal(False))
                             for k, v in self.networks.items()])
         self.state_store.save_state('network', net_records)
 
diff -r 616611521a1d -r 03d0dda70a8f tools/python/xen/xend/XendStateStore.py
--- a/tools/python/xen/xend/XendStateStore.py   Tue Mar 27 00:15:07 2007 +0100
+++ b/tools/python/xen/xend/XendStateStore.py   Tue Mar 27 00:19:20 2007 +0100
@@ -126,6 +126,13 @@ class XendStateStore:
                     if val_name not in cls_dict:
                         cls_dict[val_name] = {}
                     cls_dict[val_name][val_uuid] = None
+                elif val_type == '':
+                    # dictionary
+                    k = val_elem.getAttribute('key').encode('utf8')
+                    v = val_elem.getAttribute('value').encode('utf8')
+                    if val_name not in cls_dict:
+                        cls_dict[val_name] = {}
+                    cls_dict[val_name][k] = v
                 elif val_type == 'string':
                     cls_dict[val_name] = val_text.encode('utf8')
                 elif val_type == 'float':
@@ -197,7 +204,11 @@ class XendStateStore:
                 if type(val) == dict:
                     for val_uuid in val.keys():
                         val_node = doc.createElement(key)
-                        val_node.setAttribute('uuid', val_uuid)
+                        if key == 'other_config':
+                            val_node.setAttribute('key', str(val_uuid))
+                            val_node.setAttribute('value', str(val[val_uuid]))
+                        else:
+                            val_node.setAttribute('uuid', val_uuid)
                         node.appendChild(val_node)
                 elif type(val) in (list, tuple):
                     for val_uuid in val:

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.