ia64/xen-unstable

changeset 14570:03d0dda70a8f

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@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Tue Mar 27 00:19:20 2007 +0100 (2007-03-27)
parents 616611521a1d
children 75c797744eb4
files docs/xen-api/xenapi-datamodel.tex tools/libxen/include/xen_network.h tools/libxen/src/xen_network.c tools/python/xen/xend/XendAPI.py tools/python/xen/xend/XendNetwork.py tools/python/xen/xend/XendNode.py tools/python/xen/xend/XendStateStore.py
line diff
     1.1 --- a/docs/xen-api/xenapi-datamodel.tex	Tue Mar 27 00:15:07 2007 +0100
     1.2 +++ b/docs/xen-api/xenapi-datamodel.tex	Tue Mar 27 00:19:20 2007 +0100
     1.3 @@ -6549,6 +6549,7 @@ Quals & Field & Type & Description \\
     1.4  $\mathit{RW}$ &  {\tt name/description} & string & a notes field containg human-readable description \\
     1.5  $\mathit{RO}_\mathit{run}$ &  {\tt VIFs} & (VIF ref) Set & list of connected vifs \\
     1.6  $\mathit{RO}_\mathit{run}$ &  {\tt PIFs} & (PIF ref) Set & list of connected pifs \\
     1.7 +$\mathit{RW}$ &  {\tt other\_config} & (string $\rightarrow$ string) Map & additional configuration \\
     1.8  \hline
     1.9  \end{longtable}
    1.10  \subsection{RPCs associated with class: network}
    1.11 @@ -6801,6 +6802,145 @@ value of the field
    1.12  \vspace{0.3cm}
    1.13  \vspace{0.3cm}
    1.14  \vspace{0.3cm}
    1.15 +\subsubsection{RPC name:~get\_other\_config}
    1.16 +
    1.17 +{\bf Overview:} 
    1.18 +Get the other\_config field of the given network.
    1.19 +
    1.20 + \noindent {\bf Signature:} 
    1.21 +\begin{verbatim} ((string -> string) Map) get_other_config (session_id s, network ref self)\end{verbatim}
    1.22 +
    1.23 +
    1.24 +\noindent{\bf Arguments:}
    1.25 +
    1.26 + 
    1.27 +\vspace{0.3cm}
    1.28 +\begin{tabular}{|c|c|p{7cm}|}
    1.29 + \hline
    1.30 +{\bf type} & {\bf name} & {\bf description} \\ \hline
    1.31 +{\tt network ref } & self & reference to the object \\ \hline 
    1.32 +
    1.33 +\end{tabular}
    1.34 +
    1.35 +\vspace{0.3cm}
    1.36 +
    1.37 + \noindent {\bf Return Type:} 
    1.38 +{\tt 
    1.39 +(string $\rightarrow$ string) Map
    1.40 +}
    1.41 +
    1.42 +
    1.43 +value of the field
    1.44 +\vspace{0.3cm}
    1.45 +\vspace{0.3cm}
    1.46 +\vspace{0.3cm}
    1.47 +\subsubsection{RPC name:~set\_other\_config}
    1.48 +
    1.49 +{\bf Overview:} 
    1.50 +Set the other\_config field of the given network.
    1.51 +
    1.52 + \noindent {\bf Signature:} 
    1.53 +\begin{verbatim} void set_other_config (session_id s, network ref self, (string -> string) Map value)\end{verbatim}
    1.54 +
    1.55 +
    1.56 +\noindent{\bf Arguments:}
    1.57 +
    1.58 + 
    1.59 +\vspace{0.3cm}
    1.60 +\begin{tabular}{|c|c|p{7cm}|}
    1.61 + \hline
    1.62 +{\bf type} & {\bf name} & {\bf description} \\ \hline
    1.63 +{\tt network ref } & self & reference to the object \\ \hline 
    1.64 +
    1.65 +{\tt (string $\rightarrow$ string) Map } & value & New value to set \\ \hline 
    1.66 +
    1.67 +\end{tabular}
    1.68 +
    1.69 +\vspace{0.3cm}
    1.70 +
    1.71 + \noindent {\bf Return Type:} 
    1.72 +{\tt 
    1.73 +void
    1.74 +}
    1.75 +
    1.76 +
    1.77 +
    1.78 +\vspace{0.3cm}
    1.79 +\vspace{0.3cm}
    1.80 +\vspace{0.3cm}
    1.81 +\subsubsection{RPC name:~add\_to\_other\_config}
    1.82 +
    1.83 +{\bf Overview:} 
    1.84 +Add the given key-value pair to the other\_config field of the given
    1.85 +network.
    1.86 +
    1.87 + \noindent {\bf Signature:} 
    1.88 +\begin{verbatim} void add_to_other_config (session_id s, network ref self, string key, string value)\end{verbatim}
    1.89 +
    1.90 +
    1.91 +\noindent{\bf Arguments:}
    1.92 +
    1.93 + 
    1.94 +\vspace{0.3cm}
    1.95 +\begin{tabular}{|c|c|p{7cm}|}
    1.96 + \hline
    1.97 +{\bf type} & {\bf name} & {\bf description} \\ \hline
    1.98 +{\tt network ref } & self & reference to the object \\ \hline 
    1.99 +
   1.100 +{\tt string } & key & Key to add \\ \hline 
   1.101 +
   1.102 +{\tt string } & value & Value to add \\ \hline 
   1.103 +
   1.104 +\end{tabular}
   1.105 +
   1.106 +\vspace{0.3cm}
   1.107 +
   1.108 + \noindent {\bf Return Type:} 
   1.109 +{\tt 
   1.110 +void
   1.111 +}
   1.112 +
   1.113 +
   1.114 +
   1.115 +\vspace{0.3cm}
   1.116 +\vspace{0.3cm}
   1.117 +\vspace{0.3cm}
   1.118 +\subsubsection{RPC name:~remove\_from\_other\_config}
   1.119 +
   1.120 +{\bf Overview:} 
   1.121 +Remove the given key and its corresponding value from the other\_config
   1.122 +field of the given network.  If the key is not in that Map, then do
   1.123 +nothing.
   1.124 +
   1.125 + \noindent {\bf Signature:} 
   1.126 +\begin{verbatim} void remove_from_other_config (session_id s, network ref self, string key)\end{verbatim}
   1.127 +
   1.128 +
   1.129 +\noindent{\bf Arguments:}
   1.130 +
   1.131 + 
   1.132 +\vspace{0.3cm}
   1.133 +\begin{tabular}{|c|c|p{7cm}|}
   1.134 + \hline
   1.135 +{\bf type} & {\bf name} & {\bf description} \\ \hline
   1.136 +{\tt network ref } & self & reference to the object \\ \hline 
   1.137 +
   1.138 +{\tt string } & key & Key to remove \\ \hline 
   1.139 +
   1.140 +\end{tabular}
   1.141 +
   1.142 +\vspace{0.3cm}
   1.143 +
   1.144 + \noindent {\bf Return Type:} 
   1.145 +{\tt 
   1.146 +void
   1.147 +}
   1.148 +
   1.149 +
   1.150 +
   1.151 +\vspace{0.3cm}
   1.152 +\vspace{0.3cm}
   1.153 +\vspace{0.3cm}
   1.154  \subsubsection{RPC name:~create}
   1.155  
   1.156  {\bf Overview:} 
     2.1 --- a/tools/libxen/include/xen_network.h	Tue Mar 27 00:15:07 2007 +0100
     2.2 +++ b/tools/libxen/include/xen_network.h	Tue Mar 27 00:19:20 2007 +0100
     2.3 @@ -22,6 +22,7 @@
     2.4  #include "xen_common.h"
     2.5  #include "xen_network_decl.h"
     2.6  #include "xen_pif_decl.h"
     2.7 +#include "xen_string_string_map.h"
     2.8  #include "xen_vif_decl.h"
     2.9  
    2.10  
    2.11 @@ -68,6 +69,7 @@ typedef struct xen_network_record
    2.12      char *name_description;
    2.13      struct xen_vif_record_opt_set *vifs;
    2.14      struct xen_pif_record_opt_set *pifs;
    2.15 +    xen_string_string_map *other_config;
    2.16  } xen_network_record;
    2.17  
    2.18  /**
    2.19 @@ -220,6 +222,13 @@ xen_network_get_pifs(xen_session *sessio
    2.20  
    2.21  
    2.22  /**
    2.23 + * Get the other_config field of the given network.
    2.24 + */
    2.25 +extern bool
    2.26 +xen_network_get_other_config(xen_session *session, xen_string_string_map **result, xen_network network);
    2.27 +
    2.28 +
    2.29 +/**
    2.30   * Set the name/label field of the given network.
    2.31   */
    2.32  extern bool
    2.33 @@ -234,6 +243,30 @@ xen_network_set_name_description(xen_ses
    2.34  
    2.35  
    2.36  /**
    2.37 + * Set the other_config field of the given network.
    2.38 + */
    2.39 +extern bool
    2.40 +xen_network_set_other_config(xen_session *session, xen_network network, xen_string_string_map *other_config);
    2.41 +
    2.42 +
    2.43 +/**
    2.44 + * Add the given key-value pair to the other_config field of the given
    2.45 + * network.
    2.46 + */
    2.47 +extern bool
    2.48 +xen_network_add_to_other_config(xen_session *session, xen_network network, char *key, char *value);
    2.49 +
    2.50 +
    2.51 +/**
    2.52 + * Remove the given key and its corresponding value from the
    2.53 + * other_config field of the given network.  If the key is not in that Map,
    2.54 + * then do nothing.
    2.55 + */
    2.56 +extern bool
    2.57 +xen_network_remove_from_other_config(xen_session *session, xen_network network, char *key);
    2.58 +
    2.59 +
    2.60 +/**
    2.61   * Return a list of all the networks known to the system.
    2.62   */
    2.63  extern bool
     3.1 --- a/tools/libxen/src/xen_network.c	Tue Mar 27 00:15:07 2007 +0100
     3.2 +++ b/tools/libxen/src/xen_network.c	Tue Mar 27 00:19:20 2007 +0100
     3.3 @@ -24,6 +24,7 @@
     3.4  #include "xen_internal.h"
     3.5  #include "xen_network.h"
     3.6  #include "xen_pif.h"
     3.7 +#include "xen_string_string_map.h"
     3.8  #include "xen_vif.h"
     3.9  
    3.10  
    3.11 @@ -52,7 +53,10 @@ static const struct_member xen_network_r
    3.12            .offset = offsetof(xen_network_record, vifs) },
    3.13          { .key = "PIFs",
    3.14            .type = &abstract_type_ref_set,
    3.15 -          .offset = offsetof(xen_network_record, pifs) }
    3.16 +          .offset = offsetof(xen_network_record, pifs) },
    3.17 +        { .key = "other_config",
    3.18 +          .type = &abstract_type_string_string_map,
    3.19 +          .offset = offsetof(xen_network_record, other_config) }
    3.20      };
    3.21  
    3.22  const abstract_type xen_network_record_abstract_type_ =
    3.23 @@ -78,6 +82,7 @@ xen_network_record_free(xen_network_reco
    3.24      free(record->name_description);
    3.25      xen_vif_record_opt_set_free(record->vifs);
    3.26      xen_pif_record_opt_set_free(record->pifs);
    3.27 +    xen_string_string_map_free(record->other_config);
    3.28      free(record);
    3.29  }
    3.30  
    3.31 @@ -239,6 +244,23 @@ xen_network_get_pifs(xen_session *sessio
    3.32  
    3.33  
    3.34  bool
    3.35 +xen_network_get_other_config(xen_session *session, xen_string_string_map **result, xen_network network)
    3.36 +{
    3.37 +    abstract_value param_values[] =
    3.38 +        {
    3.39 +            { .type = &abstract_type_string,
    3.40 +              .u.string_val = network }
    3.41 +        };
    3.42 +
    3.43 +    abstract_type result_type = abstract_type_string_string_map;
    3.44 +
    3.45 +    *result = NULL;
    3.46 +    XEN_CALL_("network.get_other_config");
    3.47 +    return session->ok;
    3.48 +}
    3.49 +
    3.50 +
    3.51 +bool
    3.52  xen_network_set_name_label(xen_session *session, xen_network network, char *label)
    3.53  {
    3.54      abstract_value param_values[] =
    3.55 @@ -271,6 +293,56 @@ xen_network_set_name_description(xen_ses
    3.56  
    3.57  
    3.58  bool
    3.59 +xen_network_set_other_config(xen_session *session, xen_network network, xen_string_string_map *other_config)
    3.60 +{
    3.61 +    abstract_value param_values[] =
    3.62 +        {
    3.63 +            { .type = &abstract_type_string,
    3.64 +              .u.string_val = network },
    3.65 +            { .type = &abstract_type_string_string_map,
    3.66 +              .u.set_val = (arbitrary_set *)other_config }
    3.67 +        };
    3.68 +
    3.69 +    xen_call_(session, "network.set_other_config", param_values, 2, NULL, NULL);
    3.70 +    return session->ok;
    3.71 +}
    3.72 +
    3.73 +
    3.74 +bool
    3.75 +xen_network_add_to_other_config(xen_session *session, xen_network network, char *key, char *value)
    3.76 +{
    3.77 +    abstract_value param_values[] =
    3.78 +        {
    3.79 +            { .type = &abstract_type_string,
    3.80 +              .u.string_val = network },
    3.81 +            { .type = &abstract_type_string,
    3.82 +              .u.string_val = key },
    3.83 +            { .type = &abstract_type_string,
    3.84 +              .u.string_val = value }
    3.85 +        };
    3.86 +
    3.87 +    xen_call_(session, "network.add_to_other_config", param_values, 3, NULL, NULL);
    3.88 +    return session->ok;
    3.89 +}
    3.90 +
    3.91 +
    3.92 +bool
    3.93 +xen_network_remove_from_other_config(xen_session *session, xen_network network, char *key)
    3.94 +{
    3.95 +    abstract_value param_values[] =
    3.96 +        {
    3.97 +            { .type = &abstract_type_string,
    3.98 +              .u.string_val = network },
    3.99 +            { .type = &abstract_type_string,
   3.100 +              .u.string_val = key }
   3.101 +        };
   3.102 +
   3.103 +    xen_call_(session, "network.remove_from_other_config", param_values, 2, NULL, NULL);
   3.104 +    return session->ok;
   3.105 +}
   3.106 +
   3.107 +
   3.108 +bool
   3.109  xen_network_get_all(xen_session *session, struct xen_network_set **result)
   3.110  {
   3.111  
     4.1 --- a/tools/python/xen/xend/XendAPI.py	Tue Mar 27 00:15:07 2007 +0100
     4.2 +++ b/tools/python/xen/xend/XendAPI.py	Tue Mar 27 00:19:20 2007 +0100
     4.3 @@ -32,6 +32,7 @@ from xen.xend.XendAuthSessions import in
     4.4  from xen.xend.XendError import *
     4.5  from xen.xend.XendClient import ERROR_INVALID_DOMAIN
     4.6  from xen.xend.XendLogging import log
     4.7 +from xen.xend.XendNetwork import XendNetwork
     4.8  from xen.xend.XendTask import XendTask
     4.9  from xen.xend.XendVMMetrics import XendVMMetrics
    4.10  
    4.11 @@ -436,6 +437,10 @@ class XendAPI(object):
    4.12              'debug'        : valid_debug,
    4.13          }
    4.14  
    4.15 +        autoplug_classes = {
    4.16 +            'network' : XendNetwork
    4.17 +        }
    4.18 +
    4.19          # Cheat methods
    4.20          # -------------
    4.21          # Methods that have a trivial implementation for all classes.
    4.22 @@ -457,6 +462,41 @@ class XendAPI(object):
    4.23              setattr(cls, get_by_uuid, _get_by_uuid)
    4.24              setattr(cls, get_uuid,    _get_uuid)
    4.25  
    4.26 +
    4.27 +        # Autoplugging classes
    4.28 +        # --------------------
    4.29 +        # These have all of their methods grabbed out from the implementation
    4.30 +        # class, and wrapped up to be compatible with the Xen-API.
    4.31 +        
    4.32 +        for api_cls, impl_cls in autoplug_classes.items():
    4.33 +            getter = getattr(cls, '_%s_get' % api_cls)
    4.34 +
    4.35 +            def doit(n):
    4.36 +                dot_n = '%s.%s' % (api_cls, n)
    4.37 +                full_n = '%s_%s' % (api_cls, n)
    4.38 +                if not hasattr(cls, full_n):
    4.39 +                    f = getattr(impl_cls, n)
    4.40 +                    argcounts[dot_n] = f.func_code.co_argcount + 1
    4.41 +                    setattr(cls, full_n,
    4.42 +                            lambda s, session, ref, *args: \
    4.43 +                               xen_api_success( \
    4.44 +                                   f(getter(s, session, ref), *args)))
    4.45 +
    4.46 +            ro_attrs = getattr(cls, '%s_attr_ro' % api_cls, [])
    4.47 +            rw_attrs = getattr(cls, '%s_attr_rw' % api_cls, [])
    4.48 +            methods  = getattr(cls, '%s_methods' % api_cls, [])
    4.49 +            funcs    = getattr(cls, '%s_funcs'   % api_cls, [])
    4.50 +            
    4.51 +            for attr_name in ro_attrs + rw_attrs:
    4.52 +                doit('get_%s' % attr_name)
    4.53 +            for attr_name in rw_attrs + cls.Base_attr_rw:
    4.54 +                doit('set_%s' % attr_name)
    4.55 +            for method_name, return_type in methods + cls.Base_methods:
    4.56 +                doit('%s' % method_name)
    4.57 +            for func_name, return_type in funcs + cls.Base_funcs:
    4.58 +                doit('%s' % func_name)
    4.59 +
    4.60 +
    4.61          # Wrapping validators around XMLRPC calls
    4.62          # ---------------------------------------
    4.63  
    4.64 @@ -466,7 +506,8 @@ class XendAPI(object):
    4.65                  n_ = n.replace('.', '_')
    4.66                  try:
    4.67                      f = getattr(cls, n_)
    4.68 -                    argcounts[n] = f.func_code.co_argcount - 1
    4.69 +                    if n not in argcounts:
    4.70 +                        argcounts[n] = f.func_code.co_argcount - 1
    4.71                      
    4.72                      validators = takes_instance and validator and \
    4.73                                   [validator] or []
    4.74 @@ -916,44 +957,24 @@ class XendAPI(object):
    4.75  
    4.76      network_attr_ro = ['VIFs', 'PIFs']
    4.77      network_attr_rw = ['name_label',
    4.78 -                       'name_description']
    4.79 -    
    4.80 -    network_funcs = [('create', 'network')]
    4.81 +                       'name_description',
    4.82 +                       'other_config']
    4.83 +    network_methods = [('add_to_other_config', None),
    4.84 +                       ('remove_from_other_config', None)]
    4.85 +    network_funcs = [('create', None)]
    4.86      
    4.87 -    def network_create(self, _, name_label, name_description):
    4.88 -        return xen_api_success(
    4.89 -            XendNode.instance().network_create(name_label, name_description))
    4.90 -
    4.91 -    def network_destroy(self, _, ref):
    4.92 -        return xen_api_success(XendNode.instance().network_destroy(ref))
    4.93 -
    4.94 -    def _get_network(self, ref):
    4.95 +    def _network_get(self, _, ref):
    4.96          return XendNode.instance().get_network(ref)
    4.97  
    4.98      def network_get_all(self, _):
    4.99          return xen_api_success(XendNode.instance().get_network_refs())
   4.100  
   4.101 -    def network_get_record(self, _, ref):
   4.102 -        return xen_api_success(
   4.103 -            XendNode.instance().get_network(ref).get_record())
   4.104 -
   4.105 -    def network_get_name_label(self, _, ref):
   4.106 -        return xen_api_success(self._get_network(ref).name_label)
   4.107 -
   4.108 -    def network_get_name_description(self, _, ref):
   4.109 -        return xen_api_success(self._get_network(ref).name_description)
   4.110 +    def network_create(self, _, record):
   4.111 +        return xen_api_success(XendNode.instance().network_create(record))
   4.112  
   4.113 -    def network_get_VIFs(self, _, ref):
   4.114 -        return xen_api_success(self._get_network(ref).get_VIF_UUIDs())
   4.115 -
   4.116 -    def network_get_PIFs(self, session, ref):
   4.117 -        return xen_api_success(self._get_network(ref).get_PIF_UUIDs())
   4.118 +    def network_destroy(self, _, ref):
   4.119 +        return xen_api_success(XendNode.instance().network_destroy(ref))
   4.120  
   4.121 -    def network_set_name_label(self, _, ref, val):
   4.122 -        return xen_api_success(self._get_network(ref).set_name_label(val))
   4.123 -
   4.124 -    def network_set_name_description(self, _, ref, val):
   4.125 -        return xen_api_success(self._get_network(ref).set_name_description(val))
   4.126  
   4.127      # Xen API: Class PIF
   4.128      # ----------------------------------------------------------------
     5.1 --- a/tools/python/xen/xend/XendNetwork.py	Tue Mar 27 00:15:07 2007 +0100
     5.2 +++ b/tools/python/xen/xend/XendNetwork.py	Tue Mar 27 00:19:20 2007 +0100
     5.3 @@ -28,10 +28,17 @@ from XendLogging import log
     5.4  IP_ROUTE_RE = r'^default via ([\d\.]+) dev (\w+)'
     5.5  
     5.6  class XendNetwork:
     5.7 -    def __init__(self, uuid, name, description):
     5.8 +    def __init__(self, uuid, record):
     5.9          self.uuid = uuid
    5.10 -        self.name_label = name 
    5.11 -        self.name_description = description
    5.12 +        self.name_label = record.get('name_label', '')
    5.13 +        self.name_description = record.get('name_description', '')
    5.14 +        self.other_config = record.get('other_config', {})
    5.15 +
    5.16 +    def get_name_label(self):
    5.17 +        return self.name_label
    5.18 +
    5.19 +    def get_name_description(self):
    5.20 +        return self.name_description
    5.21  
    5.22      def set_name_label(self, new_name):
    5.23          self.name_label = new_name
    5.24 @@ -41,7 +48,7 @@ class XendNetwork:
    5.25          self.name_description = new_desc
    5.26          XendNode.instance().save_networks()
    5.27  
    5.28 -    def get_VIF_UUIDs(self):
    5.29 +    def get_VIFs(self):
    5.30          result = []
    5.31          vms = XendDomain.instance().get_all_vms()
    5.32          for vm in vms:
    5.33 @@ -52,17 +59,37 @@ class XendNetwork:
    5.34                      result.append(vif)
    5.35          return result
    5.36  
    5.37 -    def get_PIF_UUIDs(self):
    5.38 +    def get_PIFs(self):
    5.39          return [x.uuid for x in XendNode.instance().pifs.values()
    5.40                  if x.network == self]
    5.41  
    5.42 -    def get_record(self, transient = True):
    5.43 +    def get_other_config(self):
    5.44 +        return self.other_config
    5.45 +
    5.46 +    def set_other_config(self, value):
    5.47 +        self.other_config = value
    5.48 +        XendNode.instance().save_networks()
    5.49 +
    5.50 +    def add_to_other_config(self, key, value):
    5.51 +        self.other_config[key] = value
    5.52 +        XendNode.instance().save_networks()
    5.53 +
    5.54 +    def remove_from_other_config(self, key):
    5.55 +        if key in self.other_config:
    5.56 +            del self.other_config[key]
    5.57 +        XendNode.instance().save_networks()
    5.58 +
    5.59 +    def get_record(self):
    5.60 +        return self.get_record_internal(True)
    5.61 +
    5.62 +    def get_record_internal(self, transient):
    5.63          result = {
    5.64              'uuid': self.uuid,
    5.65              'name_label': self.name_label,
    5.66              'name_description': self.name_description,
    5.67 +            'other_config' : self.other_config,
    5.68          }
    5.69          if transient:
    5.70 -            result['VIFs'] = self.get_VIF_UUIDs()
    5.71 -            result['PIFs'] = self.get_PIF_UUIDs()
    5.72 +            result['VIFs'] = self.get_VIFs()
    5.73 +            result['PIFs'] = self.get_PIFs()
    5.74          return result
     6.1 --- a/tools/python/xen/xend/XendNode.py	Tue Mar 27 00:15:07 2007 +0100
     6.2 +++ b/tools/python/xen/xend/XendNode.py	Tue Mar 27 00:19:20 2007 +0100
     6.3 @@ -141,11 +141,9 @@ class XendNode:
     6.4          saved_networks = self.state_store.load_state('network')
     6.5          if saved_networks:
     6.6              for net_uuid, network in saved_networks.items():
     6.7 -                self.network_create(network.get('name_label'),
     6.8 -                                    network.get('name_description', ''),
     6.9 -                                    False, net_uuid)
    6.10 +                self.network_create(network, False, net_uuid)
    6.11          else:
    6.12 -            self.network_create('net0', '', False)
    6.13 +            self.network_create({'name_label' : 'net0' }, False)
    6.14  
    6.15          # initialise PIFs
    6.16          saved_pifs = self.state_store.load_state('pif')
    6.17 @@ -199,12 +197,10 @@ class XendNode:
    6.18  
    6.19  
    6.20  
    6.21 -    def network_create(self, name_label, name_description, persist = True,
    6.22 -                       net_uuid = None):
    6.23 +    def network_create(self, record, persist = True, net_uuid = None):
    6.24          if net_uuid is None:
    6.25              net_uuid = uuid.createString()
    6.26 -        self.networks[net_uuid] = XendNetwork(net_uuid, name_label,
    6.27 -                                              name_description)
    6.28 +        self.networks[net_uuid] = XendNetwork(net_uuid, record)
    6.29          if persist:
    6.30              self.save_networks()
    6.31          return net_uuid
    6.32 @@ -280,7 +276,7 @@ class XendNode:
    6.33          self.state_store.save_state('pif', pif_records)
    6.34  
    6.35      def save_networks(self):
    6.36 -        net_records = dict([(k, v.get_record(transient = False))
    6.37 +        net_records = dict([(k, v.get_record_internal(False))
    6.38                              for k, v in self.networks.items()])
    6.39          self.state_store.save_state('network', net_records)
    6.40  
     7.1 --- a/tools/python/xen/xend/XendStateStore.py	Tue Mar 27 00:15:07 2007 +0100
     7.2 +++ b/tools/python/xen/xend/XendStateStore.py	Tue Mar 27 00:19:20 2007 +0100
     7.3 @@ -126,6 +126,13 @@ class XendStateStore:
     7.4                      if val_name not in cls_dict:
     7.5                          cls_dict[val_name] = {}
     7.6                      cls_dict[val_name][val_uuid] = None
     7.7 +                elif val_type == '':
     7.8 +                    # dictionary
     7.9 +                    k = val_elem.getAttribute('key').encode('utf8')
    7.10 +                    v = val_elem.getAttribute('value').encode('utf8')
    7.11 +                    if val_name not in cls_dict:
    7.12 +                        cls_dict[val_name] = {}
    7.13 +                    cls_dict[val_name][k] = v
    7.14                  elif val_type == 'string':
    7.15                      cls_dict[val_name] = val_text.encode('utf8')
    7.16                  elif val_type == 'float':
    7.17 @@ -197,7 +204,11 @@ class XendStateStore:
    7.18                  if type(val) == dict:
    7.19                      for val_uuid in val.keys():
    7.20                          val_node = doc.createElement(key)
    7.21 -                        val_node.setAttribute('uuid', val_uuid)
    7.22 +                        if key == 'other_config':
    7.23 +                            val_node.setAttribute('key', str(val_uuid))
    7.24 +                            val_node.setAttribute('value', str(val[val_uuid]))
    7.25 +                        else:
    7.26 +                            val_node.setAttribute('uuid', val_uuid)
    7.27                          node.appendChild(val_node)
    7.28                  elif type(val) in (list, tuple):
    7.29                      for val_uuid in val: