Commit 8d14b30d authored by Iustin Pop's avatar Iustin Pop
Browse files

Abstract the json functions into a separate module

This simple patch adds a new module that holds the simplejson functions
for serialization/deserialization. This reduces the amount of redundant
code.

The patch also adds some normalizations to the json output:
  - the output text will always have an EOL as last char
  - extra spaces before EOL are removed

Reviewed-by: ultrotter
parent e7c6e02b
......@@ -4,7 +4,7 @@ nodist_pkgpython_PYTHON = _autoconf.py
pkgpython_PYTHON = __init__.py backend.py cli.py cmdlib.py config.py \
objects.py errors.py logger.py ssh.py utils.py rpc.py \
bdev.py hypervisor.py opcodes.py mcpu.py constants.py \
ssconf.py locking.py luxi.py jqueue.py
ssconf.py locking.py luxi.py jqueue.py serializer.py
all-local: _autoconf.py
......
......@@ -30,7 +30,6 @@ import time
import tempfile
import re
import platform
import simplejson
from ganeti import rpc
from ganeti import ssh
......@@ -43,14 +42,7 @@ from ganeti import constants
from ganeti import objects
from ganeti import opcodes
from ganeti import ssconf
# Check whether the simplejson module supports indentation
_JSON_INDENT = 2
try:
simplejson.dumps(1, indent=_JSON_INDENT)
except TypeError:
_JSON_INDENT = None
from ganeti import serializer
class LogicalUnit(object):
......@@ -3162,10 +3154,7 @@ class LUCreateInstance(LogicalUnit):
_IAllocatorAddNewInstance(al_data, op)
if _JSON_INDENT is None:
text = simplejson.dumps(al_data)
else:
text = simplejson.dumps(al_data, indent=_JSON_INDENT)
text = serializer.Dump(al_data)
result = _IAllocatorRun(self.op.iallocator, text)
......@@ -4876,7 +4865,7 @@ def _IAllocatorValidateResult(data):
"""
try:
rdict = simplejson.loads(data)
rdict = serializer.Load(data)
except Exception, err:
raise errors.OpExecError("Can't parse iallocator results: %s" % str(err))
......@@ -4968,10 +4957,7 @@ class LUTestAllocator(NoHooksLU):
else:
_IAllocatorAddRelocateInstance(data, self.op)
if _JSON_INDENT is None:
text = simplejson.dumps(data)
else:
text = simplejson.dumps(data, indent=_JSON_INDENT)
text = serializer.Dump(data)
if self.op.direction == constants.IALLOCATOR_DIR_IN:
result = text
else:
......
......@@ -42,6 +42,7 @@ from ganeti import utils
from ganeti import constants
from ganeti import rpc
from ganeti import objects
from ganeti import serializer
class ConfigWriter:
......@@ -502,7 +503,7 @@ class ConfigWriter:
f = open(self._cfg_file, 'r')
try:
try:
data = objects.ConfigData.Load(f)
data = objects.ConfigData.FromDict(serializer.Load(f.read()))
except Exception, err:
raise errors.ConfigurationError(err)
finally:
......@@ -560,11 +561,12 @@ class ConfigWriter:
if destination is None:
destination = self._cfg_file
self._BumpSerialNo()
txt = serializer.Dump(self._config_data.ToDict())
dir_name, file_name = os.path.split(destination)
fd, name = tempfile.mkstemp('.newconfig', file_name, dir_name)
f = os.fdopen(fd, 'w')
try:
self._config_data.Dump(f)
f.write(txt)
os.fsync(f.fileno())
finally:
f.close()
......
......@@ -27,7 +27,6 @@ pass to and from external parties.
"""
import simplejson
import ConfigParser
import re
from cStringIO import StringIO
......@@ -40,14 +39,6 @@ __all__ = ["ConfigObject", "ConfigData", "NIC", "Disk", "Instance",
"OS", "Node", "Cluster"]
# Check whether the simplejson module supports indentation
_JSON_INDENT = 2
try:
simplejson.dumps(1, indent=_JSON_INDENT)
except TypeError:
_JSON_INDENT = None
class ConfigObject(object):
"""A generic config object.
......@@ -90,34 +81,6 @@ class ConfigObject(object):
if name in self.__slots__:
setattr(self, name, state[name])
def Dump(self, fobj):
"""Dump to a file object.
"""
data = self.ToDict()
if _JSON_INDENT is None:
simplejson.dump(data, fobj)
else:
simplejson.dump(data, fobj, indent=_JSON_INDENT)
@classmethod
def Load(cls, fobj):
"""Load data from the given stream.
"""
return cls.FromDict(simplejson.load(fobj))
def Dumps(self):
"""Dump and return the string representation."""
buf = StringIO()
self.Dump(buf)
return buf.getvalue()
@classmethod
def Loads(cls, data):
"""Load data from a string."""
return cls.Load(StringIO(data))
def ToDict(self):
"""Convert to a dict holding only standard python types.
......
#
#
# Copyright (C) 2007, 2008 Google Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of 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.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
"""Serializer abstraction module
This module introduces a simple abstraction over the serialization
backend (currently json).
"""
import simplejson
import ConfigParser
import re
# Check whether the simplejson module supports indentation
_JSON_INDENT = 2
try:
simplejson.dumps(1, indent=_JSON_INDENT)
except TypeError:
_JSON_INDENT = None
_RE_EOLSP = re.compile('\s+$', re.MULTILINE)
def Dump(data):
"""Serialize a given object.
"""
if _JSON_INDENT is None:
txt = simplejson.dumps(data)
else:
txt = simplejson.dumps(data, indent=_JSON_INDENT)
if not txt.endswith('\n'):
txt += '\n'
txt = _RE_EOLSP.sub("", txt)
return txt
def Load(txt):
"""Unserialize data from a string.
"""
return simplejson.loads(txt)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment