1*2d9fd380Sjfb8856606#! /usr/bin/env python3 2*2d9fd380Sjfb8856606# SPDX-License-Identifier: BSD-3-Clause 3*2d9fd380Sjfb8856606# Copyright(c) 2020 Intel Corporation 4*2d9fd380Sjfb8856606 5*2d9fd380Sjfb8856606""" 6*2d9fd380Sjfb8856606Script to be used with V2 Telemetry. 7*2d9fd380Sjfb8856606Allows the user input commands and read the Telemetry response. 8*2d9fd380Sjfb8856606""" 9*2d9fd380Sjfb8856606 10*2d9fd380Sjfb8856606import socket 11*2d9fd380Sjfb8856606import os 12*2d9fd380Sjfb8856606import glob 13*2d9fd380Sjfb8856606import json 14*2d9fd380Sjfb8856606import readline 15*2d9fd380Sjfb8856606 16*2d9fd380Sjfb8856606# global vars 17*2d9fd380Sjfb8856606TELEMETRY_VERSION = "v2" 18*2d9fd380Sjfb8856606CMDS = [] 19*2d9fd380Sjfb8856606 20*2d9fd380Sjfb8856606 21*2d9fd380Sjfb8856606def read_socket(sock, buf_len, echo=True): 22*2d9fd380Sjfb8856606 """ Read data from socket and return it in JSON format """ 23*2d9fd380Sjfb8856606 reply = sock.recv(buf_len).decode() 24*2d9fd380Sjfb8856606 try: 25*2d9fd380Sjfb8856606 ret = json.loads(reply) 26*2d9fd380Sjfb8856606 except json.JSONDecodeError: 27*2d9fd380Sjfb8856606 print("Error in reply: ", reply) 28*2d9fd380Sjfb8856606 sock.close() 29*2d9fd380Sjfb8856606 raise 30*2d9fd380Sjfb8856606 if echo: 31*2d9fd380Sjfb8856606 print(json.dumps(ret)) 32*2d9fd380Sjfb8856606 return ret 33*2d9fd380Sjfb8856606 34*2d9fd380Sjfb8856606 35*2d9fd380Sjfb8856606def handle_socket(path): 36*2d9fd380Sjfb8856606 """ Connect to socket and handle user input """ 37*2d9fd380Sjfb8856606 sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) 38*2d9fd380Sjfb8856606 global CMDS 39*2d9fd380Sjfb8856606 print("Connecting to " + path) 40*2d9fd380Sjfb8856606 try: 41*2d9fd380Sjfb8856606 sock.connect(path) 42*2d9fd380Sjfb8856606 except OSError: 43*2d9fd380Sjfb8856606 print("Error connecting to " + path) 44*2d9fd380Sjfb8856606 sock.close() 45*2d9fd380Sjfb8856606 return 46*2d9fd380Sjfb8856606 json_reply = read_socket(sock, 1024) 47*2d9fd380Sjfb8856606 output_buf_len = json_reply["max_output_len"] 48*2d9fd380Sjfb8856606 49*2d9fd380Sjfb8856606 # get list of commands for readline completion 50*2d9fd380Sjfb8856606 sock.send("/".encode()) 51*2d9fd380Sjfb8856606 CMDS = read_socket(sock, output_buf_len, False)["/"] 52*2d9fd380Sjfb8856606 53*2d9fd380Sjfb8856606 # interactive prompt 54*2d9fd380Sjfb8856606 text = input('--> ').strip() 55*2d9fd380Sjfb8856606 while text != "quit": 56*2d9fd380Sjfb8856606 if text.startswith('/'): 57*2d9fd380Sjfb8856606 sock.send(text.encode()) 58*2d9fd380Sjfb8856606 read_socket(sock, output_buf_len) 59*2d9fd380Sjfb8856606 text = input('--> ').strip() 60*2d9fd380Sjfb8856606 sock.close() 61*2d9fd380Sjfb8856606 62*2d9fd380Sjfb8856606 63*2d9fd380Sjfb8856606def readline_complete(text, state): 64*2d9fd380Sjfb8856606 """ Find any matching commands from the list based on user input """ 65*2d9fd380Sjfb8856606 all_cmds = ['quit'] + CMDS 66*2d9fd380Sjfb8856606 if text: 67*2d9fd380Sjfb8856606 matches = [c for c in all_cmds if c.startswith(text)] 68*2d9fd380Sjfb8856606 else: 69*2d9fd380Sjfb8856606 matches = all_cmds 70*2d9fd380Sjfb8856606 return matches[state] 71*2d9fd380Sjfb8856606 72*2d9fd380Sjfb8856606 73*2d9fd380Sjfb8856606readline.parse_and_bind('tab: complete') 74*2d9fd380Sjfb8856606readline.set_completer(readline_complete) 75*2d9fd380Sjfb8856606readline.set_completer_delims(readline.get_completer_delims().replace('/', '')) 76*2d9fd380Sjfb8856606 77*2d9fd380Sjfb8856606# Path to sockets for processes run as a root user 78*2d9fd380Sjfb8856606for f in glob.glob('/var/run/dpdk/*/dpdk_telemetry.%s' % TELEMETRY_VERSION): 79*2d9fd380Sjfb8856606 handle_socket(f) 80*2d9fd380Sjfb8856606# Path to sockets for processes run as a regular user 81*2d9fd380Sjfb8856606for f in glob.glob('%s/dpdk/*/dpdk_telemetry.%s' % 82*2d9fd380Sjfb8856606 (os.environ.get('XDG_RUNTIME_DIR', '/tmp'), TELEMETRY_VERSION)): 83*2d9fd380Sjfb8856606 handle_socket(f) 84