From 54d73fa2ef3455b60659ddba6f434d17fa4d45a0 Mon Sep 17 00:00:00 2001 From: Kostiantyn Kostiuk Date: Thu, 3 Oct 2024 14:53:49 +0300 Subject: [PATCH] Add fake SNMP reset tool The flush test sends an SNMP request to PDU to reset the power on the hardware PC. As the flush test sends only one type of request we don't need to parse it and can just wait for any UDP packet and perform a hard reset of the VM. Signed-off-by: Kostiantyn Kostiuk --- bin/fake-snmp-reset | 71 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100755 bin/fake-snmp-reset diff --git a/bin/fake-snmp-reset b/bin/fake-snmp-reset new file mode 100755 index 00000000..097ffad7 --- /dev/null +++ b/bin/fake-snmp-reset @@ -0,0 +1,71 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# Intended to be usable as a standalone script +# it is not a part of the AutoHCK module + +require 'json' +require 'logger' +require 'socket' + +class SnmpReset + def initialize(logger, socket_file) + @logger = logger + + @socket_file = socket_file + + @qmp_connected = false + end + + def connect_socket + @logger.info "Initializing QMP session for #{@socket_file}" + @qmp_socket = UNIXSocket.new(@socket_file) + end + + def run + @logger.info 'Initializing UDP socket' + UDPSocket.open do |socket| + socket.bind('0.0.0.0', 'snmp') + @logger.info "Listening on #{socket.local_address.inspect_sockaddr}" + + count = 0 + + loop do + _, addr = socket.recvfrom(512) + + @logger.info "Received data from #{addr[3]}:#{addr[1]}" + + unless @qmp_connected + connect_socket + send_cmd 'qmp_capabilities' + @qmp_connected = true + end + + count += 1 + send_cmd 'system_reset' + @logger.info "Rebooting... #{count}" + end + end + end + + private + + def send_cmd(cmd) + @logger.info "Sending #{cmd} via QMP" + @qmp_socket.write JSON.dump({ 'execute' => cmd }) + @qmp_socket.flush + + loop do + response = JSON.parse(@qmp_socket.readline) + break response['return'] if response.key?('return') + raise response['error'].to_s if response.key?('error') + end + end +end + +log = Logger.new('fake-snmp-reset.txt') +log.level = Logger::DEBUG +log.info "START #{ARGV}" + +snmp = SnmpReset.new(log, ARGV[0]) +snmp.run