-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathbmc.py
124 lines (103 loc) · 4.19 KB
/
bmc.py
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
from logger import logger
import time
from ailib import Redfish
from dataclasses import dataclass
@dataclass(frozen=True)
class BmcConfig:
url: str
user: str = "root"
password: str = "calvin"
class BMC:
def __init__(self, full_url: str, user: str = "root", password: str = "calvin"):
self.url = full_url
self.user = user
self.password = password
logger.info(f"{full_url} {user} {password}")
@staticmethod
def from_bmc_config(bmc_config: BmcConfig) -> 'BMC':
return BMC.from_bmc(bmc_config.url, bmc_config.user, bmc_config.password)
@staticmethod
def from_url(url: str, user: str = "root", password: str = "calvin") -> 'BMC':
url = f"{url}/redfish/v1/Systems/System.Embedded.1"
return BMC(url, user, password)
@staticmethod
def from_bmc(ip_or_hostname: str, user: str = "root", password: str = "calvin") -> 'BMC':
if ip_or_hostname == "":
raise ValueError("BMC not defined")
url = f"https://{ip_or_hostname}/redfish/v1/Systems/System.Embedded.1"
return BMC(url, user, password)
"""
Red Fish is used to boot ISO images with virtual media.
Make sure redfish is enabled on your server. You can verify this by
visiting the BMC's web address:
https://<ip>/redfish/v1/Systems/System.Embedded.1 (For Dell)
Red Fish uses HTTP POST messages to trigger actions. Some requires
data. However the Red Fish library takes care of this for you.
Red Fish heavily depends on iDRAC and IPMI working. For Dell servers:
Log into iDRAC, default user is "root" and default password is "calvin".
1) Try rebooting iDRAC
a) Go to "Maintenance" tab at the top
b) Go to the "Diagnostics" sub-tab below the "Maintenance" panel.
c) Press the "Reboot iDRAC"
d) Wait a while for iDRAC to come up.
e) Once the web interface is available, go back to the "Dashboard" tab.
f) Monitor the system to post after the "Dell" blue screen.
2) Try upgrading firmware
a) Go to "Maintenance" tab at the top
b) Go to the "System Update" sub-tab below the "Maintenance" panel.
c) Change the "Location Type" to "HTTP"
d) Under the "HTTP Server Settings", set the "HTTP Address" to be
"downloads.dell.com".
e) Click "Check for Update".
f) Depending on the missing updates, select what is needed then press
"Install and Reboot"
g) Wait a while for iDRAC to come up.
h) Once the web interface is available, go back to the "Dashboard" tab.
i) Monitor the system to post after the "Dell" blue screen.
"""
def boot_iso_redfish(self, iso_path: str, retries: int = 10, retry_delay: int = 60) -> None:
def boot_iso_with_retry(iso_path: str) -> None:
logger.info(iso_path)
logger.info(f"Trying to boot {self.url} using {iso_path}")
red = self._redfish()
try:
red.eject_iso()
except Exception as e:
logger.info(e)
logger.info("eject failed, but continuing")
logger.info(f"inserting iso {iso_path}")
red.insert_iso(iso_path)
try:
red.set_iso_once()
except Exception as e:
logger.info(e)
raise e
logger.info("setting to boot from iso")
red.restart()
time.sleep(10)
logger.info(f"Finished sending boot to {self.url}")
assert ":" in iso_path
for attempt in range(retries):
try:
boot_iso_with_retry(iso_path)
return
except Exception as e:
if attempt == retries - 1:
raise e
else:
time.sleep(retry_delay)
def _redfish(self) -> Redfish:
return Redfish(self.url, self.user, self.password, model='dell', debug=False)
def stop(self) -> None:
self._redfish().stop()
def start(self) -> None:
self._redfish().start()
def cold_boot(self) -> None:
self.stop()
time.sleep(10)
self.start()
time.sleep(5)
def main() -> None:
pass
if __name__ == "__main__":
main()