1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
import copy
from opendc.models.model import Model
from opendc.models.rack import Rack
from opendc.util import database, exceptions
class Machine(Model):
JSON_TO_PYTHON_DICT = {
'machine': {
'id': 'id',
'rackId': 'rack_id',
'position': 'position',
'tags': 'tags',
'cpuIds': 'cpu_ids',
'gpuIds': 'gpu_ids',
'memoryIds': 'memory_ids',
'storageIds': 'storage_ids'
}
}
PATH = '/v1/simulations/{simulationId}/datacenters/{datacenterId}/rooms/{roomId}/tiles/{tileId}/rack/machines'
TABLE_NAME = 'machines'
COLUMNS = ['id', 'rack_id', 'position']
COLUMNS_PRIMARY_KEY = ['id']
device_table_to_attribute = {
'cpus': 'cpu_ids',
'gpus': 'gpu_ids',
'memories': 'memory_ids',
'storages': 'storage_ids'
}
def _update_devices(self, before_insert):
"""Update this Machine's devices in the database."""
for device_table in self.device_table_to_attribute.keys():
# First, create the statements to execute
statements = []
values = []
# First, delete current machine-device links
statement = 'DELETE FROM machine_{} WHERE machine_id = %s'.format(device_table)
database.execute(statement, (before_insert.id,))
# Then, add current ones
for device_id in getattr(before_insert, before_insert.device_table_to_attribute[device_table]):
statement = 'INSERT INTO machine_{} (machine_id, {}) VALUES (%s, %s)'.format(
device_table,
before_insert.device_table_to_attribute[device_table][:-1]
)
database.execute(statement, (before_insert.id, device_id))
@classmethod
def from_tile_id_and_rack_position(cls, tile_id, position):
"""Get a Rack from the ID of the tile its Rack is on, and its position in the Rack."""
try:
rack = Rack.from_tile_id(tile_id)
except:
return cls(id = -1)
try:
statement = 'SELECT id FROM machines WHERE rack_id = %s AND position = %s'
machine_id = database.fetchone(statement, (rack.id, position))[0]
except:
return cls(id = -1)
return cls.from_primary_key((machine_id,))
def google_id_has_at_least(self, google_id, authorization_level):
"""Return True if the user has at least the given auth level over this Machine."""
# Get the Rack
try:
rack = Rack.from_primary_key((self.rack_id,))
except exceptions.RowNotFoundError:
return False
# Check the Rack's Authorization
return rack.google_id_has_at_least(google_id, authorization_level)
def insert(self):
"""Insert this Machine by also updating its devices."""
before_insert = copy.deepcopy(self)
super(Machine, self).insert()
before_insert.id = self.id
self._update_devices(before_insert)
def read(self):
"""Read this Machine by also getting its CPU, GPU, Memory and Storage IDs."""
super(Machine, self).read()
for device_table in self.device_table_to_attribute.keys():
statement = 'SELECT * FROM machine_{} WHERE machine_id = %s'.format(device_table)
results = database.fetchall(statement, (self.id,))
device_ids = []
for row in results:
device_ids.append(row[2])
setattr(self, self.device_table_to_attribute[device_table], device_ids)
setattr(self, 'tags', [])
def update(self):
"""Update this Machine by also updating its devices."""
before_update = copy.deepcopy(self)
super(Machine, self).update()
before_update.id = self.id
self._update_devices(before_update)
|