|
1
|
|
|
"""Data structures for computer information.""" |
|
2
|
|
|
|
|
3
|
1 |
|
import uuid |
|
4
|
1 |
|
import socket |
|
5
|
1 |
|
import logging |
|
6
|
|
|
|
|
7
|
1 |
|
import yorm |
|
|
|
|
|
|
8
|
|
|
|
|
9
|
1 |
|
from .base import NameMixin |
|
10
|
|
|
|
|
11
|
|
|
|
|
12
|
1 |
|
log = logging.getLogger(__name__) |
|
13
|
|
|
|
|
14
|
|
|
|
|
15
|
1 |
|
@yorm.attr(name=yorm.types.String) |
|
16
|
1 |
|
@yorm.attr(hostname=yorm.types.String) |
|
17
|
1 |
|
@yorm.attr(address=yorm.types.String) |
|
18
|
1 |
|
class Computer(NameMixin, yorm.types.AttributeDictionary): |
|
19
|
|
|
"""A dictionary of identifying computer information.""" |
|
20
|
|
|
|
|
21
|
1 |
|
def __init__(self, name, hostname=None, address=None): |
|
22
|
1 |
|
super().__init__() |
|
23
|
1 |
|
self.name = name |
|
24
|
1 |
|
self.address = address or self.get_address() |
|
25
|
1 |
|
self.hostname = hostname or self.get_hostname() |
|
26
|
|
|
|
|
27
|
1 |
|
@staticmethod |
|
28
|
1 |
|
def get_address(node=None): |
|
29
|
|
|
"""Get this computer's MAC address.""" |
|
30
|
1 |
|
if node is None: |
|
31
|
1 |
|
node = uuid.getnode() |
|
32
|
1 |
|
return ':'.join(("%012X" % node)[i:i + 2] for i in range(0, 12, 2)) |
|
33
|
|
|
|
|
34
|
1 |
|
@staticmethod |
|
35
|
|
|
def get_hostname(): |
|
36
|
|
|
"""Get this computer's hostname.""" |
|
37
|
1 |
|
return socket.gethostname() |
|
38
|
|
|
|
|
39
|
|
|
|
|
40
|
1 |
|
@yorm.attr(all=Computer) |
|
|
|
|
|
|
41
|
1 |
|
class Computers(yorm.types.SortedList): |
|
42
|
|
|
"""A list of computers.""" |
|
43
|
|
|
|
|
44
|
1 |
|
@property |
|
45
|
|
|
def names(self): |
|
46
|
|
|
"""Get a list of all computers' labels.""" |
|
47
|
1 |
|
return [c.name for c in self] |
|
48
|
|
|
|
|
49
|
1 |
|
def get(self, name): |
|
50
|
|
|
"""Get the computer with the given name.""" |
|
51
|
1 |
|
computer = self.find(name) |
|
52
|
1 |
|
assert computer, name |
|
53
|
1 |
|
return computer |
|
54
|
|
|
|
|
55
|
1 |
|
def find(self, name): |
|
56
|
|
|
"""Find the computer with the given name, else None.""" |
|
57
|
1 |
|
log.debug("Finding computer for '%s'...", name) |
|
58
|
1 |
|
for computer in self: |
|
59
|
1 |
|
if computer == name: |
|
60
|
1 |
|
return computer |
|
61
|
|
|
|
|
62
|
1 |
|
def match(self, partial): |
|
63
|
|
|
"""Find a computer with a similar name.""" |
|
64
|
1 |
|
log.debug("Finding computer similar to '%s'...", partial) |
|
65
|
1 |
|
for computer in self: |
|
66
|
1 |
|
if partial.lower() in computer.name.lower(): |
|
67
|
1 |
|
return computer |
|
68
|
|
|
|
|
69
|
1 |
|
def get_current(self): |
|
70
|
|
|
"""Get the current computer's information.""" |
|
71
|
1 |
|
this = Computer(None) |
|
72
|
|
|
|
|
73
|
|
|
# Search for a matching address |
|
74
|
1 |
|
for other in self: |
|
75
|
1 |
|
if this.address == other.address: |
|
76
|
1 |
|
other.hostname = this.hostname |
|
77
|
1 |
|
return other |
|
78
|
|
|
|
|
79
|
|
|
# Else, search for a matching hostname |
|
80
|
1 |
|
for other in self: |
|
81
|
1 |
|
if this.hostname == other.hostname: |
|
82
|
1 |
|
other.address = this.address |
|
83
|
1 |
|
return other |
|
84
|
|
|
|
|
85
|
|
|
# Else, this is a new computer |
|
86
|
1 |
|
this.name = self.generate_name(this) |
|
87
|
1 |
|
assert this.name != 'localhost' |
|
88
|
1 |
|
log.debug("New computer: %s", this) |
|
89
|
1 |
|
self.append(this) |
|
|
|
|
|
|
90
|
1 |
|
return this |
|
91
|
|
|
|
|
92
|
1 |
|
def generate_name(self, computer): |
|
93
|
|
|
"""Generate a new label for a computer.""" |
|
94
|
1 |
|
name = computer.hostname.lower().split('.')[0] |
|
95
|
1 |
|
copy = 1 |
|
96
|
1 |
|
while name in self.names: |
|
97
|
1 |
|
copy += 1 |
|
98
|
1 |
|
name2 = "{}-{}".format(name, copy) |
|
99
|
1 |
|
if name2 not in self.names: |
|
100
|
1 |
|
name = name2 |
|
101
|
|
|
return name |
|
102
|
|
|
|
This can be caused by one of the following:
1. Missing Dependencies
This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.
2. Missing __init__.py files
This error could also result from missing
__init__.pyfiles in your module folders. Make sure that you place one file in each sub-folder.