Add comments and standard headers for publication

This commit is contained in:
Joshua Boniface 2017-06-03 02:50:32 -04:00
parent 3d3a7f0e96
commit 36fa70fecc
3 changed files with 186 additions and 101 deletions

221
bmc.sh
View File

@ -1,5 +1,23 @@
#!/bin/bash #!/bin/bash
#
# bmc.sh - BMC command shell
#
# This program works as the main user shell for the RPi BMC. It provides a
# command-line interface for interfacing with the running bmcd daemon
# program as well as a few distinct functions such as a serial console, as
# well as managing the BMC itself (e.g. BMC hostname, IP address, or host
# system name. It is designed to be started automatically on login to the
# BMC as the 'bmc' user, e.g. with the following passwd file entry:
# bmc:x:2000:2000:BMC:/home/dir:/path/to/bmc.sh
#
# Has dependencies on the 'bmcd' and 'screen' utilities.
#
# Part of the RPiBMC project - (c)2017 Joshua Boniface
# This software is licenced under the terms of the GNU GPL version 3. For
# details please see LICENSE
#
stty eof undef stty eof undef
stty intr undef stty intr undef
@ -79,7 +97,10 @@ readpower() {
fi fi
} }
# Read the power state
readpower readpower
# Print our login splash
echo echo
echo -e "--------------------" echo -e "--------------------"
echo -e "| Raspberry Pi BMC |" echo -e "| Raspberry Pi BMC |"
@ -90,102 +111,108 @@ echo -e "Host state: ${powerstate}"
echo echo
help help
echo echo
# Main loop
while true; do while true; do
stty eof undef stty eof undef
stty intr undef stty intr undef
echo -en "\e[1m\e[34m[$(hostname)]>\e[0m "
read input # Prompt
case ${input} in echo -en "\e[1m\e[34m[$(hostname)]>\e[0m "
'state') # Read input
readpower read input
echo -e "Host state: ${powerstate}" # Process input
echo case ${input} in
;; 'state')
'console') readpower
echo "Starting console..." echo -e "Host state: ${powerstate}"
# Connect to screen, or start it echo
sudo screen -r serialconsole &>/dev/null || sudo screen -S serialconsole /dev/ttyUSB0 115200 ;;
# If the user killed screen, restart it - just in case 'console')
pgrep screen &>/dev/null || sudo screen -S serialconsole /dev/ttyUSB0 115200 echo "Starting console..."
echo # Connect to screen, or start it
;; sudo screen -r serialconsole &>/dev/null || sudo screen -S serialconsole /dev/ttyUSB0 115200
'power') # If the user killed screen, restart it - just in case
powersw_press pgrep screen &>/dev/null || sudo screen -S serialconsole /dev/ttyUSB0 115200
readpower echo
echo -e "Host state: ${powerstate}" ;;
echo 'power')
;; powersw_press
'reset') readpower
resetsw_press echo -e "Host state: ${powerstate}"
echo echo
;; ;;
'kill') 'reset')
powersw_hold resetsw_press
readpower echo
echo -e "Host state: ${powerstate}" ;;
echo 'kill')
;; powersw_hold
'locate') readpower
locate_on echo -e "Host state: ${powerstate}"
echo echo
;; ;;
'unlocate') 'locate')
locate_off locate_on
echo echo
;; ;;
'help') 'unlocate')
help locate_off
echo echo
;; ;;
'bmc') 'help')
bmcinfo help
echo echo
;; ;;
'hostname') 'bmc')
echo -n "Enter new hostname: " bmcinfo
read newhostname echo
sethostname ${newhostname} ;;
echo 'hostname')
;; echo -n "Enter new hostname: "
'host') read newhostname
echo -n "Enter new host system name: " sethostname ${newhostname}
read newhost echo
sethost ${newhost} ;;
echo -n "Update BMC hostname to '${newhost}-bmc'? (y/N) " 'host')
read updatehostnameyn echo -n "Enter new host system name: "
if [[ "${updatehostnameyn}" =~ "y" ]]; then read newhost
sethostname "${newhost}-bmc" sethost ${newhost}
fi echo -n "Update BMC hostname to '${newhost}-bmc'? (y/N) "
;; read updatehostnameyn
'password') if [[ "${updatehostnameyn}" =~ "y" ]]; then
echo -n "Enter new BMC password: " sethostname "${newhost}-bmc"
read -s password_1 fi
echo ;;
echo -n "Reenter new BMC password: " 'password')
read -s password_2 echo -n "Enter new BMC password: "
echo read -s password_1
if [ "${password_1}" == "${password_2}" ]; then echo
setpassword "${password_1}" echo -n "Reenter new BMC password: "
else read -s password_2
echo "Passwords to not match!" echo
fi if [ "${password_1}" == "${password_2}" ]; then
echo setpassword "${password_1}"
;; else
'shell') echo "Passwords to not match!"
stty sane fi
/bin/bash echo
help ;;
echo 'shell')
;; stty sane
'exit'|'logout') /bin/bash
exit 0 help
;; echo
'') ;;
continue 'exit'|'logout')
;; exit 0
*) ;;
echo "Invalid command." '')
echo continue
;; ;;
esac *)
echo "Invalid command."
echo
;;
esac
done done

31
bmcd
View File

@ -1,27 +1,47 @@
#!/usr/bin/env python #!/usr/bin/env python
#
# bmcd - BMC Daemon program
#
# This program works as a background daemon for the RPi BMC. It provides
# functionality to interface with the GPIOs in an asynchronous way via two
# pipes, one read-only and one write-only from the outside perspective. The read
# pipe provides the current system power status while the write pipe listens
# for commands.
#
# Part of the RPiBMC project - (c)2017 Joshua Boniface
# This software is licenced under the terms of the GNU GPL version 3. For
# details please see LICENSE
#
import socket, os, time, struct import socket, os, time, struct
from threading import Thread, Event from threading import Thread, Event
from daemon import runner from daemon import runner
import RPi.GPIO as GPIO import RPi.GPIO as GPIO
# These are GPIOs 1-4
gpio_rsw = 17 gpio_rsw = 17
gpio_psw = 18 gpio_psw = 18
gpio_state = 27 gpio_state = 27
gpio_pled = 22 gpio_pled = 22
# The pipes and PID file (sorry I manage this here...)
bmcd_state = '/run/bmcd/bmcd.state' bmcd_state = '/run/bmcd/bmcd.state'
bmcd_cmd = '/run/bmcd/bmcd.cmd' bmcd_cmd = '/run/bmcd/bmcd.cmd'
pidfile = '/run/bmcd/bmcd.pid' pidfile = '/run/bmcd/bmcd.pid'
# Event for LED flash (i.e. locator)
is_pled_flashing = Event() is_pled_flashing = Event()
# Turn the power LED on
def powerled_on(): def powerled_on():
GPIO.output(gpio_pled, 1) GPIO.output(gpio_pled, 1)
# Turn the power LED off
def powerled_off(): def powerled_off():
GPIO.output(gpio_pled, 0) GPIO.output(gpio_pled, 0)
# Flash the power LED
def powerled_flash(is_pled_flashing): def powerled_flash(is_pled_flashing):
while is_pled_flashing.isSet(): while is_pled_flashing.isSet():
GPIO.output(gpio_pled, 1) GPIO.output(gpio_pled, 1)
@ -31,29 +51,35 @@ def powerled_flash(is_pled_flashing):
is_pled_flashing.clear() is_pled_flashing.clear()
return return
# Press the power button
def powersw_press(): def powersw_press():
GPIO.output(gpio_psw, 1) GPIO.output(gpio_psw, 1)
time.sleep(0.5) time.sleep(0.5)
GPIO.output(gpio_psw, 0) GPIO.output(gpio_psw, 0)
# Hold the power button (8 seconds)
def powersw_hold(): def powersw_hold():
GPIO.output(gpio_psw, 1) GPIO.output(gpio_psw, 1)
time.sleep(8) time.sleep(8)
GPIO.output(gpio_psw, 0) GPIO.output(gpio_psw, 0)
# Press the reset button
def resetsw_press(): def resetsw_press():
GPIO.output(gpio_rsw, 1) GPIO.output(gpio_rsw, 1)
time.sleep(0.5) time.sleep(0.5)
GPIO.output(gpio_rsw, 0) GPIO.output(gpio_rsw, 0)
# Turn on the locator (subthread)
def locate_on(): def locate_on():
is_pled_flashing.set() is_pled_flashing.set()
t = Thread(name='non-block', target=powerled_flash, args=(is_pled_flashing,)) t = Thread(name='non-block', target=powerled_flash, args=(is_pled_flashing,))
t.start() t.start()
# Turn off the locator
def locate_off(): def locate_off():
is_pled_flashing.clear() is_pled_flashing.clear()
# Read a command from the pipe
def readcmd(): def readcmd():
fcmd = open(bmcd_cmd, 'r+', 0) fcmd = open(bmcd_cmd, 'r+', 0)
while True: while True:
@ -63,6 +89,7 @@ def readcmd():
except: except:
pass pass
# Main loop
def writestate(is_pled_flashing): def writestate(is_pled_flashing):
while True: while True:
state_now = GPIO.input(gpio_state) state_now = GPIO.input(gpio_state)
@ -77,7 +104,7 @@ def writestate(is_pled_flashing):
time.sleep(1) time.sleep(1)
# Main app definiton - sets default states and runs main loop
class App(): class App():
def __init__(self): def __init__(self):
self.stdin_path = '/dev/null' self.stdin_path = '/dev/null'
@ -106,7 +133,7 @@ class App():
while True: while True:
pass pass
# App definition - start it up
app = App() app = App()
daemon_runner = runner.DaemonRunner(app) daemon_runner = runner.DaemonRunner(app)
daemon_runner.do_action() daemon_runner.do_action()

View File

@ -1,17 +1,48 @@
#!/bin/bash -e #!/bin/bash -e
# #
# rc.local for RPiBMC # rc.local - BMC startup rc.local file
#
# This file replaces the default rc.local (or can be appended to it) to
# ensure the BMC daemon and serial console sesson start at boot and have
# the proper permissions for bmc.sh to work as expected. It also writes
# some useful debug information to /var/log/rc.local.log should later boot
# analysis be needed.
#
# Has dependencies on the 'bmcd' and 'screen' utilities.
#
# Part of the RPiBMC project - (c)2017 Joshua Boniface
# This software is licenced under the terms of the GNU GPL version 3. For
# details please see LICENSE
#
# Write all output to rc.local.log file
exec 1>>/var/log/rc.local.log exec 1>>/var/log/rc.local.log
exec 2>>/var/log/rc.local.log exec 2>>/var/log/rc.local.log
# Write when we booted
echo "#" echo "#"
echo "# Boot at $(date) " echo "# Boot at $(date) "
echo "#" echo "#"
# Turn on verbose BASH mode for logging visibility
set -x set -x
/usr/bin/screen -dmS serialconsole /dev/ttyUSB0 115200
# Start the screen session to /dev/ttyAMA0 (115200 baud)
/usr/bin/screen -dmS serialconsole /dev/ttyAMA0 115200
# Check if the temporary bmcd directory exists, or create it
test -d /run/bmcd || mkdir /run/bmcd test -d /run/bmcd || mkdir /run/bmcd
# Start the bmcd daemon
/home/bmc/rpibmc/bmcd start /home/bmc/rpibmc/bmcd start
# Wait 5 seconds for the daemon startup routines
sleep 5 sleep 5
# Change the temporary bmcd directory permissions to allow gpio group (only) access
chgrp -R gpio /run/bmcd chgrp -R gpio /run/bmcd
chmod -R 770 /run/bmcd chmod -R 770 /run/bmcd
# Turn off verbose BASH mode and exit 0 (as per rc.local requirements)
set +x set +x
exit 0 exit 0