mirror of
https://github.com/checkpoint-restore/criu
synced 2025-09-01 14:55:39 +00:00
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: Pavel Emelyanov <xemul@parallels.com> Acked-by: Ruslan Kuprieiev <kupruser@gmail.com>
This commit is contained in:
15
crit
15
crit
@@ -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):
|
|||||||
|
|
||||||
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:
|
|||||||
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:
|
|||||||
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:
|
|||||||
|
|
||||||
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:
|
|||||||
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:
|
|||||||
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 = {
|
|||||||
'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):
|
|||||||
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 = {
|
|||||||
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):
|
|||||||
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):
|
|||||||
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
|
||||||
|
Reference in New Issue
Block a user