urllib.error.URLError: <urlopen error [Errno 113] No route to host>
07:49 06 Nov 2019

I'm trying to create a master, agent script where the master gets information out of the agent. Information such as:

  • Hostname usage
  • CPU usage
  • Disk usage
  • Memory usage

I have put this in to a function that returns the data. When the data is about to be send I get the error:

Traceback (most recent call last):
  File "./agent.py", line 42, in 
    send_data(out_data)
  File "./agent.py", line 36, in send_data
    with urllib.request.urlopen(req) as response :
  File "/usr/lib64/python3.6/urllib/request.py", line 223, in urlopen
    return opener.open(url, data, timeout)
  File "/usr/lib64/python3.6/urllib/request.py", line 526, in open
    response = self._open(req, data)
  File "/usr/lib64/python3.6/urllib/request.py", line 544, in _open
    '_open', req)
  File "/usr/lib64/python3.6/urllib/request.py", line 504, in _call_chain
    result = func(*args)
  File "/usr/lib64/python3.6/urllib/request.py", line 1346, in http_open
    return self.do_open(http.client.HTTPConnection, req)
  File "/usr/lib64/python3.6/urllib/request.py", line 1320, in do_open
    raise URLError(err)
urllib.error.URLError: 

I checked if there is connection between the two VM's. One's IP address = 192.168.234.2 (master), the others 192.168.234.10 (agent). The routing tabel from the agent shows routing table agent and here is a ping between the two ping

Agent.py

#!/bin/python3
##importeer onderstaande modules om deze te gebruiken##
import psutil
import socket
import time
import urllib.parse
import urllib.request

url = 'http://192.168.234.2/cgi-bin/master.py'
##de output van bovenstaande prints word geplaats in deze variabel om deze in onderstaande variabelen door te sturen##


#De dictionairys worden klaar gezet om gebruikt te worden
def save_data():
    return {
        'machine'   : socket.gethostname(),
        'memory'    : psutil.virtual_memory()[2],
        'disk'      : psutil.disk_usage('/').percent,
        'cpu'       : psutil.cpu_percent()
    }

#De data wordt in de dictionairys gezet
def print_info(out_data):
    print ("Het script heeft gedraaid op: ",time.strftime('%m/%d/%Y %H:%M:%S'))
    print ('De naam van deze host machine is:', out_data['machine'])
    print ('Het geheugen is ', out_data['memory'],'% in gebruik')
    print ('De schijf is ', out_data['disk'],'% vol')
    print ('Het CPU percentage dat in gebruik is: ', out_data['cpu'])

#de data wordt naar de master verzonden
def send_data(out_data):
    data = urllib.parse.urlencode(out_data)
    data = data.encode('ascii')
    req = urllib.request.Request(url, data)
    with urllib.request.urlopen(req) as response :
        the_page = response.read()


out_data = save_data()        
print_info(out_data)
send_data(out_data)

Master.py

#!/usr/bin/python3
###importeren van modules om deze vervolgens te kunnen gebruiken in het script###
import cgi, cgitb
import matplotlib.pyplot as plt
import io
import sqlite3

#maak een instance van een field storage
cgitb.enable()
form = cgi.FieldStorage()

#het verkrijgen van data van de velden die vanuit de agent worden opgestuurd.
def get_data():
    system_data = {
    "machine" : form.getvalue('machine'),
    "cpu": form.getvalue('cpu'),
    "mem": form.getvalue('mem'),
    "disk": form.getvalue('disk')}
    return system_data

#print ("Content-type:text/html\n\n")

current_data = get_data()

con = sqlite3.connect('toets_school.db')
cursor = con.cursor()
cursor.execute("CREATE TABLE if NOT EXISTS gegevens ('machine',VARCHAR, 'cpu' float, 'mem' float, 'disk' float)")
cursor.execute("INSERT INTO gegevens (machine, cpu, mem, disk) VALUES ('"+str(current_data["machine"])+"','"+str(current_data["cpu"])+"', '"+str(current_data["mem"])+"', '"+str(current_data["disk"])+"')")
cursor.execute("SELECT cpu, mem, disk FROM gegevens WHERE machine = '"+str(current_data["machine"]+"'")
data = cursor.fetchall()

cpulijst = []
memlijst = []
disklijst = []

for info in data:
    cpulijst.append(info[0])
    memlijst.append(info[1])
    disklijst.append(info[2])

#print(data)
con.commit()
get_data()

print (cpulijst)
def chart_cpu():
    plt.plot(cpulijst)
    plt.title("CPU gebruik")
    plt.xlabel('minuten')
    plt.ylabel('percentage(%)')
    plt.grid(True)
    plt.savefig("cpu.png")
    plt.show()

def chart_memory():
    plt.plot(memlijst)
    plt.title("Geheugen")
    plt.xlabel('minuten')
    plt.ylabel('percentage (%)')
    plt.grid(True)
    plt.savefig("memory.png")
    plt.show()

def chart_disk_usage():
    plt.plot(disklijst)
    plt.title("Schuifruimte")
    plt.xlabel('minuten')
    plt.ylabel('(%)in gebruik')
    plt.grid(True)
    plt.savefig("disk_usage.png")
    plt.show()

chart_cpu()
chart_disk_usage()
chart_memory()

print ("Content-type:text/html\n\n")
print ("
") print ('De naam van deze machine is :', machine) print ("
") print ("Website HAF sportschool") print("") print("") print ("") conn.close()

I expect that the agent, sends the information is stored in function save_data get passed in to out_data. And that the data gets send in the function def send_data to the master.

Edit: After the commend from Bill Huneke, much thanks for that. The first issue is solved. With the Linux commands:

sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --reload

I was able to able to curl master.py. Now my issue is that the database on the master is getting filled only with 'None'.

Anyone that know's how to fix this one?

python-3.x linux centos7