Set draft mode; started new post on the RPi BMC

This commit is contained in:
Joshua Boniface 2017-02-10 02:22:55 -05:00
parent 245215783d
commit 6ae362b9c6
4 changed files with 81 additions and 0 deletions

View File

@ -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!

View File

@ -5,6 +5,7 @@ Tags = ["homelab", "cableporn", "blse"]
date = "2016-10-18T22:54:45-04:00" date = "2016-10-18T22:54:45-04:00"
menu = "main" menu = "main"
title = "Anatomy of a Homelab, part I - Meatspace" title = "Anatomy of a Homelab, part I - Meatspace"
draft = true
+++ +++

View File

@ -5,6 +5,7 @@ Tags = ["x-y problem", "post-rot", "internet"]
date = "2016-11-19T00:54:55-05:00" date = "2016-11-19T00:54:55-05:00"
menu = "main" menu = "main"
title = "Post-rot and you!" title = "Post-rot and you!"
draft = true
+++ +++

BIN
static/images/bmcshell.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB