mirror of
https://github.com/ceph/ceph
synced 2025-03-10 10:19:26 +00:00
there are couple factors we should consider when choosing between BytesIO and StringIO: - if the producer is producing binary - if we are expecting binary - if the layers in between them are doing the decoding/encoding automatically. in our case, the producer is either the ChannelFile instances returned by paramiko.SSHClient or subprocess.CompletedProcess insances returned by subprocess.run(). the former are file-like objects opened in "r" mode, but their contents are decoded with utf-8 when reading if ChannelFile.FLAG_BINARY is not specified. that's why we always try to add this flag in orchestra/run.py when collecting the stdout and stderr from paramiko.SSHClient after executing a command. back in python2, this works just fine. as we don't differentiate bytes from str by then. but in python3, we have to make a decision. in the case of ceph-objectstore-tool (COT for short), it does not produce binary and we don't check its output with binary, so, if neither Remote.run() nor LocalRemote.run() decodes/encodes for us, it's fine. so it boils down to `copy_to_log()`: i think we we should respect the consumer's expectation, and only decode the output if a StringIO is passed in as stdout or stderr. as we always log the output with logging we could either set `ChannelFile.FLAG_BINARY` depending on the type of `capture` or not. if it's not set, paramiko will return str (bytes) on python2, and str on python3. if it's not set paramiko will return str (bytes) on python2, and bytes on python3. if there is non-ASCII in the output, logging will bail fail with `UnicodeDecodeError` exception. and paramiko throws the same exception when trying to decode for us if `ChannelFile.FLAG_BINARY` is not specified. so to ensure that we always have logging messages no matter if the producer follows the rule of "use StringIO if you only emit text" or not, we have to use `ChannelFile.FLAG_BINARY`, and force paramiko to send us the bytes. but we still have the luxury to use StringIO and do the decode when the caller asks for str explicitly. that'd save the pain of using `str.decode()` or `six.ensure_str()` everywhere even if we can assure that the program does not write binary. Signed-off-by: Kefu Chai <kchai@redhat.com> |
||
---|---|---|
.. | ||
cephfs | ||
mgr | ||
tests | ||
util | ||
__init__.py | ||
admin_socket.py | ||
autotest.py | ||
aver.py | ||
barbican.py | ||
blktrace.py | ||
boto.cfg.template | ||
cbt.py | ||
ceph_client.py | ||
ceph_deploy.py | ||
ceph_fuse.py | ||
ceph_manager.py | ||
ceph_objectstore_tool.py | ||
ceph_test_case.py | ||
ceph.conf.template | ||
ceph.py | ||
cephadm.conf | ||
cephadm.py | ||
cephfs_test_runner.py | ||
cephfs_upgrade_snap.py | ||
check_counter.py | ||
cifs_mount.py | ||
cram.py | ||
create_verify_lfn_objects.py | ||
daemonwatchdog.py | ||
devstack.py | ||
die_on_err.py | ||
divergent_priors2.py | ||
divergent_priors.py | ||
dnsmasq.py | ||
dump_stuck.py | ||
ec_lost_unfound.py | ||
exec_on_cleanup.py | ||
filestore_idempotent.py | ||
fs.py | ||
kclient.py | ||
keystone.py | ||
locktest.py | ||
logrotate.conf | ||
lost_unfound.py | ||
manypools.py | ||
mds_creation_failure.py | ||
mds_pre_upgrade.py | ||
mds_thrash.py | ||
metadata.yaml | ||
mon_clock_skew_check.py | ||
mon_recovery.py | ||
mon_thrash.py | ||
multibench.py | ||
netem.py | ||
object_source_down.py | ||
omapbench.py | ||
openssl_keys.py | ||
osd_backfill.py | ||
osd_failsafe_enospc.py | ||
osd_max_pg_per_osd.py | ||
osd_recovery.py | ||
peer.py | ||
peering_speed_test.py | ||
populate_rbd_pool.py | ||
qemu.py | ||
rados.py | ||
radosbench.py | ||
radosbenchsweep.py | ||
radosgw_admin_rest.py | ||
radosgw_admin.py | ||
ragweed.py | ||
rbd_fio.py | ||
rbd_fsx.py | ||
rbd_mirror_thrash.py | ||
rbd_mirror.py | ||
rbd.py | ||
rebuild_mondb.py | ||
reg11184.py | ||
rep_lost_unfound_delete.py | ||
repair_test.py | ||
resolve_stuck_peering.py | ||
restart.py | ||
rgw_logsocket.py | ||
rgw_multi | ||
rgw_multisite_tests.py | ||
rgw_multisite.py | ||
rgw.py | ||
s3a_hadoop.py | ||
s3tests_java.py | ||
s3tests.py | ||
samba.py | ||
scrub_test.py | ||
scrub.py | ||
systemd.py | ||
tempest.py | ||
teuthology_integration.py | ||
tgt.py | ||
thrash_pool_snaps.py | ||
thrasher.py | ||
thrashosds-health.yaml | ||
thrashosds.py | ||
tox.py | ||
userdata_setup.yaml | ||
userdata_teardown.yaml | ||
vault.py | ||
vstart_runner.py | ||
watch_notify_same_primary.py | ||
watch_notify_stress.py | ||
workunit.py |