From 3ff4a4a2f24d2bc6c45379c0cc326d5db1ad7beb Mon Sep 17 00:00:00 2001 From: Pierrick Louin Date: Tue, 13 Oct 2020 19:02:16 +0200 Subject: NFVBENCH-184: Add a feature (+ options) allowing to change ownership of shared log & result files Change-Id: Id77426dade28aed48986ce6c18db6a193da5b6ed Signed-off-by: Pierrick Louin --- nfvbench/cfg.default.yaml | 26 ++++++++++++++++++++++++-- nfvbench/nfvbench.py | 31 ++++++++++++++++++++++++++++++- nfvbench/utils.py | 8 ++++++-- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/nfvbench/cfg.default.yaml b/nfvbench/cfg.default.yaml index 80d5b68..26df919 100644 --- a/nfvbench/cfg.default.yaml +++ b/nfvbench/cfg.default.yaml @@ -351,14 +351,15 @@ cores_used: intf_speed_used: intf_speed_detected: -# Add cache size in packet generation for TRex field engine (FE). +# A cache size value is passed to the TRex field engine (FE) at packet generation. +# Can be overridden by --cache-size # More information for TRex performance: # https://trex-tgn.cisco.com/trex/doc/trex_stateless.html#_tutorial_field_engine_significantly_improve_performance # If cache_size = 0 (or empty): no cache will be used by TRex (default) # If cache_size < 0: cache_size will be set to flow count value cache_size: 0 # The cache size is actually limited by the number of 64B mbufs configured in the trex platform configuration (see Trex manual 6.2.2. Memory section configuration) -# Note that the resulting value is finally clipped to 10000, whatever the requested size is (by design limitation). +# Note that the resulting value is finally capped to 10000, whatever the requested size is (by design limitation). # Trex will use 1 x 64B mbuf per pre-built cached packet, assuming 1 pre-built cached packet per flow, it means for very large number of flows, the number of configured mbuf_64 will need to be set accordingly. mbuf_64: @@ -795,6 +796,26 @@ debug: false # Defaults to disabled log_file: +# One can specify a user ID for changing ownership of output log/json files +# - empty: depends on file existency +# . yes? replacement, owner is unchanged +# . no ? creation with root as user +# - 0: this is the root user ID +# - other: will corresponds (or not) to an existing user/group in the host +# (the current user ID can be obtained with the command 'id -u') +# Can be overriden by --user-id +# Consider also that the default value below is overridable by a USER_ID env variable, +# if nfvbench is run into a container, this information can be passed at its creation. +# The overall precedence rule is: 'default_config (this) < env < config < command_line' +user_id: + +# Similarly, the group ID is defined +# Can be overriden by --group-id +# Default may be set through env GROUP_ID +# Caveat: user and group with a same name may have different numerical IDs +# (the current group ID can be obtained with the command 'id -g') +group_id: + # When enabled, all results and/or logs will be sent to a fluentd servers at the requested IPs and ports # A list of one or more fluentd servers identified by their IPs and port numbers should be given. # For each recipient it is possible to enable both sending logs and performance @@ -845,6 +866,7 @@ user_label: # (the command-line parameter value is expressed as a json object string) user_info: + # THESE FIELDS SHOULD BE USED VERY RARELY OR ON PURPOSE # Skip vswitch configuration and retrieving of stats diff --git a/nfvbench/nfvbench.py b/nfvbench/nfvbench.py index 314b828..da069bf 100644 --- a/nfvbench/nfvbench.py +++ b/nfvbench/nfvbench.py @@ -165,7 +165,9 @@ class NFVBench(object): self.config.service_chain, self.config.service_chain_count, self.config.flow_count, - self.config.frame_sizes) + self.config.frame_sizes, + self.config.user_id, + self.config.group_id) def _update_config(self, opts): """Recalculate the running config based on the base config and opts. @@ -560,6 +562,20 @@ def _parse_opts_from_cli(): default=False, help='Disable latency measurements (no streams)') + parser.add_argument('--user-id', dest='user_id', + type=int_arg, + metavar='', + action='store', + default=None, + help='Change json/log files ownership with this user (int)') + + parser.add_argument('--group-id', dest='group_id', + type=int_arg, + metavar='', + action='store', + default=None, + help='Change json/log files ownership with this group (int)') + parser.add_argument('--debug-mask', dest='debug_mask', type=int_arg, metavar='', @@ -633,6 +649,12 @@ def main(): log.setup() # load default config file config, default_cfg = load_default_config() + # possibly override the default user_id & group_id values + if 'USER_ID' in os.environ: + config.user_id = int(os.environ['USER_ID']) + if 'GROUP_ID' in os.environ: + config.group_id = int(os.environ['GROUP_ID']) + # create factory for platform specific classes try: factory_module = importlib.import_module(config['factory_module']) @@ -771,6 +793,13 @@ def main(): # add file log if requested if config.log_file: log.add_file_logger(config.log_file) + # possibly change file ownership + uid = config.user_id + gid = config.group_id + if gid is None: + gid = uid + if uid is not None: + os.chown(config.log_file, uid, gid) openstack_spec = config_plugin.get_openstack_spec() if config.openrc_file \ else None diff --git a/nfvbench/utils.py b/nfvbench/utils.py index 2ce735b..6da14ed 100644 --- a/nfvbench/utils.py +++ b/nfvbench/utils.py @@ -51,7 +51,7 @@ def timeout(seconds=10, error_message=os.strerror(errno.ETIME)): def save_json_result(result, json_file, std_json_path, service_chain, service_chain_count, - flow_count, frame_sizes): + flow_count, frame_sizes, user_id=None, group_id=None): """Save results in json format file.""" filepaths = [] if json_file: @@ -71,6 +71,11 @@ def save_json_result(result, json_file, std_json_path, service_chain, service_ch sort_keys=True, separators=(',', ': '), default=lambda obj: obj.to_json()) + # possibly change file ownership + if group_id is None: + group_id = user_id + if user_id is not None: + os.chown(file_path, user_id, group_id) def dict_to_json_dict(record): @@ -155,7 +160,6 @@ def get_intel_pci(nic_slot=None, nic_ports=None): return pcis - def parse_flow_count(flow_count): flow_count = str(flow_count) input_fc = flow_count -- cgit 1.2.3-korg