Add comments and standard headers for publication
This commit is contained in:
parent
3d3a7f0e96
commit
36fa70fecc
221
bmc.sh
221
bmc.sh
|
@ -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
31
bmcd
|
@ -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()
|
||||||
|
|
||||||
|
|
35
rc.local
35
rc.local
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue