Commit 0d2aeb35 authored by Pavel Emelyanov's avatar Pavel Emelyanov

crit: Get rid of --format option

I plan to mark some fields as IP address and print them respectively.
The --format hex is not nice switch for this and introducing one more
(--format hex ipadd) is too bad.

So let's fix the cirt API to be simple and stupid. By default crit
generates canonical one-line JSON. With --pretty option it splits the
output into lines, adds indentation and prints hex as hex and IP as
IP.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Acked-by: 's avatarRuslan Kuprieiev <kupruser@gmail.com>
parent 46b7f13c
...@@ -17,14 +17,8 @@ def handle_cmdline_opts(): ...@@ -17,14 +17,8 @@ def handle_cmdline_opts():
parser.add_argument('-o', parser.add_argument('-o',
'--out', '--out',
help = 'output file (stdout by default)') help = 'output file (stdout by default)')
parser.add_argument('-f', parser.add_argument('--pretty', help = 'Multiline with indents and some numerical fields in field-specific format',
'--format', action = 'store_true')
choices = ['raw', 'nice', 'hex'],
nargs = '+',
default = [],
help = 'raw - all in one line\n'\
'nice - add indents and newlines to look nice(default for stdout)\n'\
'hex - print int fields as hex strings where suitable(could be combined with others)')
opts = vars(parser.parse_args()) opts = vars(parser.parse_args())
...@@ -45,10 +39,9 @@ def outf(opts): ...@@ -45,10 +39,9 @@ def outf(opts):
def decode(opts): def decode(opts):
indent = None indent = None
img = pycriu.images.load(inf(opts), opts['format']) img = pycriu.images.load(inf(opts), opts['pretty'])
# For stdout --format nice is set by default. if opts['pretty']:
if 'nice' in opts['format'] or ('raw' not in opts['format'] and opts['out'] == None):
indent = 4 indent = 4
f = outf(opts) f = outf(opts)
......
...@@ -59,7 +59,7 @@ class entry_handler: ...@@ -59,7 +59,7 @@ class entry_handler:
self.payload = payload self.payload = payload
self.extra_handler = extra_handler self.extra_handler = extra_handler
def load(self, f, fmt = None): def load(self, f, pretty = False):
""" """
Convert criu image entries from binary format to dict(json). Convert criu image entries from binary format to dict(json).
Takes a file-like object and returnes a list with entries in Takes a file-like object and returnes a list with entries in
...@@ -77,7 +77,7 @@ class entry_handler: ...@@ -77,7 +77,7 @@ class entry_handler:
break break
size, = struct.unpack('i', buf) size, = struct.unpack('i', buf)
pb.ParseFromString(f.read(size)) pb.ParseFromString(f.read(size))
entry = pb2dict.pb2dict(pb, fmt) entry = pb2dict.pb2dict(pb, pretty)
# Read extra # Read extra
if self.extra_handler: if self.extra_handler:
...@@ -87,12 +87,12 @@ class entry_handler: ...@@ -87,12 +87,12 @@ class entry_handler:
return entries return entries
def loads(self, s, fmt = None): def loads(self, s, pretty = False):
""" """
Same as load(), but takes a string as an argument. Same as load(), but takes a string as an argument.
""" """
f = io.BytesIO(s) f = io.BytesIO(s)
return self.load(f, fmt) return self.load(f, pretty)
def dump(self, entries, f): def dump(self, entries, f):
""" """
...@@ -131,7 +131,7 @@ class pagemap_handler: ...@@ -131,7 +131,7 @@ class pagemap_handler:
that it has a header of pagemap_head type followed by entries that it has a header of pagemap_head type followed by entries
of pagemap_entry type. of pagemap_entry type.
""" """
def load(self, f, fmt = None): def load(self, f, pretty = False):
entries = [] entries = []
pb = pagemap_head() pb = pagemap_head()
...@@ -141,15 +141,15 @@ class pagemap_handler: ...@@ -141,15 +141,15 @@ class pagemap_handler:
break break
size, = struct.unpack('i', buf) size, = struct.unpack('i', buf)
pb.ParseFromString(f.read(size)) pb.ParseFromString(f.read(size))
entries.append(pb2dict.pb2dict(pb, fmt)) entries.append(pb2dict.pb2dict(pb, pretty))
pb = pagemap_entry() pb = pagemap_entry()
return entries return entries
def loads(self, s, fmt = None): def loads(self, s, pretty = False):
f = io.BytesIO(s) f = io.BytesIO(s)
return self.load(f, fmt) return self.load(f, pretty)
def dump(self, entries, f): def dump(self, entries, f):
pb = pagemap_head() pb = pagemap_head()
...@@ -277,7 +277,7 @@ handlers = { ...@@ -277,7 +277,7 @@ handlers = {
'IPCNS_MSG' : entry_handler(ipc_msg_entry) 'IPCNS_MSG' : entry_handler(ipc_msg_entry)
} }
def load(f, fmt = None): def load(f, pretty = False):
""" """
Convert criu image from binary format to dict(json). Convert criu image from binary format to dict(json).
Takes a file-like object to read criu image from. Takes a file-like object to read criu image from.
...@@ -300,16 +300,16 @@ def load(f, fmt = None): ...@@ -300,16 +300,16 @@ def load(f, fmt = None):
raise Exception("No handler found for image with such magic "+m) raise Exception("No handler found for image with such magic "+m)
image['magic'] = m image['magic'] = m
image['entries'] = handler.load(f, fmt) image['entries'] = handler.load(f, pretty)
return image return image
def loads(s, fmt = None): def loads(s, pretty = False):
""" """
Same as load(), but takes a string. Same as load(), but takes a string.
""" """
f = io.BytesIO(s) f = io.BytesIO(s)
return load(f, fmt) return load(f, pretty)
def dump(img, f): def dump(img, f):
""" """
......
...@@ -43,23 +43,19 @@ _basic_cast = { ...@@ -43,23 +43,19 @@ _basic_cast = {
def _marked_as_hex(field): def _marked_as_hex(field):
return field.GetOptions().Extensions[opts_pb2.criu].hex return field.GetOptions().Extensions[opts_pb2.criu].hex
def _pb2dict_cast(field, value, fmt = None, is_hex = False): def _pb2dict_cast(field, value, pretty = False, is_hex = False):
if not is_hex: if not is_hex:
is_hex = _marked_as_hex(field) is_hex = _marked_as_hex(field)
if fmt:
print_hex = 'hex' in fmt
else:
print_hex = False
if field.type == FD.TYPE_MESSAGE: if field.type == FD.TYPE_MESSAGE:
return pb2dict(value, fmt, is_hex) return pb2dict(value, pretty, is_hex)
elif field.type == FD.TYPE_BYTES: elif field.type == FD.TYPE_BYTES:
return value.encode('base64') return value.encode('base64')
elif field.type == FD.TYPE_ENUM: elif field.type == FD.TYPE_ENUM:
return field.enum_type.values_by_number.get(value, None).name return field.enum_type.values_by_number.get(value, None).name
elif field.type in _basic_cast: elif field.type in _basic_cast:
cast = _basic_cast[field.type] cast = _basic_cast[field.type]
if (cast == int or cast == long) and is_hex and print_hex: if (cast == int or cast == long) and is_hex and pretty:
# Fields that have (criu).hex = true option set # Fields that have (criu).hex = true option set
# should be stored in hex string format. # should be stored in hex string format.
return "0x%x" % value return "0x%x" % value
...@@ -68,7 +64,7 @@ def _pb2dict_cast(field, value, fmt = None, is_hex = False): ...@@ -68,7 +64,7 @@ def _pb2dict_cast(field, value, fmt = None, is_hex = False):
else: else:
raise Exception("Field(%s) has unsupported type %d" % (field.name, field.type)) raise Exception("Field(%s) has unsupported type %d" % (field.name, field.type))
def pb2dict(pb, fmt = None, is_hex = False): def pb2dict(pb, pretty = False, is_hex = False):
""" """
Convert protobuf msg to dictionary. Convert protobuf msg to dictionary.
Takes a protobuf message and returns a dict. Takes a protobuf message and returns a dict.
...@@ -78,9 +74,9 @@ def pb2dict(pb, fmt = None, is_hex = False): ...@@ -78,9 +74,9 @@ def pb2dict(pb, fmt = None, is_hex = False):
if field.label == FD.LABEL_REPEATED: if field.label == FD.LABEL_REPEATED:
d_val = [] d_val = []
for v in value: for v in value:
d_val.append(_pb2dict_cast(field, v, fmt, is_hex)) d_val.append(_pb2dict_cast(field, v, pretty, is_hex))
else: else:
d_val = _pb2dict_cast(field, value, fmt, is_hex) d_val = _pb2dict_cast(field, value, pretty, is_hex)
d[field.name] = d_val d[field.name] = d_val
return d return d
......
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