diff --git a/content/post/a-raspberry-pi-bmc.md b/content/post/a-raspberry-pi-bmc.md new file mode 100644 index 0000000..a2044a5 --- /dev/null +++ b/content/post/a-raspberry-pi-bmc.md @@ -0,0 +1,79 @@ ++++ +class = "post" +date = "2017-02-10T01:35:38-05:00" +tags = [] +title = "Build A Raspberry Pi BMC" +type = "post" +weight = 1 +draft = true + ++++ + +IPMI BMCs are pretty ubiquitous in the datacenter and enterprise computing, because in a warehouse full of computers, finding and walking up to one just to reset it or check its console is quite daunting. The same goes for a home server: it may just be in my basement, but in a closed-up rack it becomes a huge hassle to manage a machine without IPMI. I try to get it on every motherboard I buy, but currently my Ceph nodes are running with motherboards that lack built-in IPMI. To make them fully-remote-manageable, I decided they needed a BMC. + +## Enter the Raspberry Pi + +If you don't know what it is, the Rapberry Pi is a small single-board computer, featuring an ARM SOC, Ethernet, USB, video, audio, and most importantly, GPIO, powered by MicroUSB and running the Debian distribution '[Raspbian](https://www.raspberrypi.org/downloads/raspbian/)'. The GPIO pins allow, with a simple utility or Python library, one to controll or read information from various devices. The GPIO header also features a serial port which must be manually enabled. + +These features make the Raspberry Pi a perfect fit for a BMC. Low-power usage and an external USB power source means it can be kept on irrespective of the host state. The GPIOs allow on to control a power switch, reset switch, read from the power LED, and generally do a basic suite of server management tasks. And finally the built-in serial connected to a motherboard COM header allows a remote console. The perfect little BMC. + +## The hardware + +Write stuff + +## The software + + Most traditional BMCs are managed via a (terrible) Web UI, which is often prone to breakage or other failures. And often these BMCs are incredibly complex, featuring dozens of menus and gigantic Flash monstrosities just to view their state. By using the Raspberry Pi, a seeming limitation - SSH-only access - becomes a benefit: it becomes trivial to connect to the BMC from a terminal, check the power state or serial console, turn on/off/reset a host, and then disconnect. No crummy web page or point-and-click menu system! + +The software side started out as a basic Raspbian system, however I wanted to make it a little more "BMC-like", in a sense stripped-down and easy-to-use with a small set of commands. I started by writing a simple "shell" emulator in BASH, and using a constant loop and hostname prompt along with `stty` to keep it focused and running. Each command triggers a function which performs its specific job and then returns to the "shell". While `bash` is available also, it should rarely be needed. + +The actual software doing the heavy lifting is a combination of `screen`, to view the host system serial console, and the `gpio` utility by WiringPi (Debian package `wiringpi`). The `screen` session is configured to start automatically at BMC boot to ensure all serial output is captured and stored for later analysis - a major problem with the (few) SSH-based BMCs I've tried! The `gpio` program makes writing and reading the GPIO pins simple and easy, returning 0 or 1 for the low/high states and easily writing states. By writing the BMB shell in `bash`, I was able to get all the flexibility I wanted without any programming overhead; the whole thing is under 200 lines. + +![Shell example](/images/bmcshell.png) + +For example, here is the `powersw` function, which manages the power button for the `powersw` and `kill` commands. By introducing a delay, we can even simulate a power-button force-off event for the `kill` task and avoid messing with the raw power: + +``` +powersw() { + if [ "$1" == "hard" ]; then + delay=10 + echo -n "Holding power switch... " + else + delay=0 + echo -n "Pressing power switch... " + fi + gpio mode 1 out + gpio write 1 1 + sleep $delay + gpio write 1 0 + sleep 1 + echo "done." +} +``` + +Simply by setting the GPIO high, we simulate a button press, and then by setting the GPIO low, we release the simulated button. The result is a very convincing replica of the standard IPMI/BMC power control functionality. Another feature is to obtain the current system power status (shown multiple times in the image above). This function reads instead of writes the GPIO, in this case the front power LED, and reports the result, colour and all: + +``` +readpower() { + gpio mode 2 in + powerstate_raw=$(gpio read 2) + if [ "${powerstate_raw}" -eq 1 ]; then + powerstate="\e[32mOn\e[0m" + else + powerstate="\e[31mOff\e[0m" + fi +} +``` + +The entire code of the BMC "shell" can be found on my [GitHub](https://github.com/joshuaboniface), and is called via a small hack to the `/etc/passwd` file for the `root` user, starting by default and terminating the SSH session on exit: + +``` +#root:x:0:0:root:/root:/bin/bash +root:x:0:0:root:/root:/root/bmc.sh +``` + +Finally we're able to set the host system's name (for display when logging in) via the file `/etc/bmchost`, which makes deploying an image and setting the name trivial. + +## Conclusion + +I hope you've found this post interesting and useful - if you have some IPMI-less systems you want to manage remotely, I definitely recommend you try it out. If you have any questions or comments, shoot me an e-mail! diff --git a/content/post/anatomy-of-a-homelab-I.md b/content/post/anatomy-of-a-homelab-I.md index 1288112..11a1c2a 100644 --- a/content/post/anatomy-of-a-homelab-I.md +++ b/content/post/anatomy-of-a-homelab-I.md @@ -5,6 +5,7 @@ Tags = ["homelab", "cableporn", "blse"] date = "2016-10-18T22:54:45-04:00" menu = "main" title = "Anatomy of a Homelab, part I - Meatspace" +draft = true +++ diff --git a/content/post/post-rot-and-you.md b/content/post/post-rot-and-you.md index 7c72baa..93f03c5 100644 --- a/content/post/post-rot-and-you.md +++ b/content/post/post-rot-and-you.md @@ -5,6 +5,7 @@ Tags = ["x-y problem", "post-rot", "internet"] date = "2016-11-19T00:54:55-05:00" menu = "main" title = "Post-rot and you!" +draft = true +++ diff --git a/static/images/bmcshell.png b/static/images/bmcshell.png new file mode 100644 index 0000000..dbe2c66 Binary files /dev/null and b/static/images/bmcshell.png differ