Add 'amboar/obmc-scripts/' from commit '291f081c7dd6cd107ffcaa7af3ede7500b7f7e35'
git-subtree-dir: amboar/obmc-scripts
git-subtree-mainline: 87d27a16765f621cf2b4242bf70d4ce63b371bb0
git-subtree-split: 291f081c7dd6cd107ffcaa7af3ede7500b7f7e35
diff --git a/amboar/obmc-scripts/LICENSE b/amboar/obmc-scripts/LICENSE
new file mode 100644
index 0000000..78e3d2c
--- /dev/null
+++ b/amboar/obmc-scripts/LICENSE
@@ -0,0 +1,14 @@
+Copyright 2017 IBM Corp.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
diff --git a/amboar/obmc-scripts/netboot/README.md b/amboar/obmc-scripts/netboot/README.md
new file mode 100644
index 0000000..717f156
--- /dev/null
+++ b/amboar/obmc-scripts/netboot/README.md
@@ -0,0 +1,28 @@
+Netboot a remote OpenBMC host via telnet (and hopefully at some stage, ssh).
+
+To configure, edit `${HOME}/.config/obmc-scripts/netboot` to configure a
+machine:
+
+```
+[foo]
+platform = "bar"
+user = "baz"
+password = "quux"
+
+ # telnet serial server
+ [foo.console]
+ host = "1.2.3.4"
+ port = 5678
+
+ [foo.u-boot]
+ commands = [
+ "setenv bootfile fitImage",
+ "tftp",
+ ]
+```
+
+Then netboot your machine:
+
+```
+$ ./netboot foo
+```
diff --git a/amboar/obmc-scripts/netboot/netboot b/amboar/obmc-scripts/netboot/netboot
new file mode 100755
index 0000000..6843de8
--- /dev/null
+++ b/amboar/obmc-scripts/netboot/netboot
@@ -0,0 +1,112 @@
+#!/usr/bin/env python3
+
+import argparse
+import sys
+import time
+import toml
+from os import path
+from telnetlib import Telnet
+from types import MethodType
+from xdg import BaseDirectory
+
+def expect_or_raise(conn, patterns, timeout=None):
+ i, m, d = conn.expect([bytes(p, 'ascii') for p in patterns], timeout)
+ if i == -1:
+ msg = "Match failed, expected '%s', got '%s'" % (str(patterns), d)
+ print(msg, file=sys.stderr)
+ raise ValueError
+ return i, m, d
+
+def encode_and_write(conn, comm="", sep="\n"):
+ # Slow down the writes to help poor ol' serial-over-telnet
+ for c in comm + sep:
+ conn.write(bytes(c, 'ascii'))
+ time.sleep(0.01)
+
+def init_telnet(host, port=0, timeout=None):
+ conn = Telnet(host, port, timeout)
+ conn.encode_and_write = MethodType(encode_and_write, conn)
+ conn.expect_or_raise = MethodType(expect_or_raise, conn)
+ return conn
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("machine", nargs="?")
+ parser.add_argument("-l", "--list-machines", action="store_true")
+ parser.add_argument("-i", "--initramfs", action="store_true")
+ args = parser.parse_args()
+
+ confbase = BaseDirectory.save_config_path("obmc-scripts")
+ conffile = path.join(confbase, "netboot")
+ if not path.exists(conffile):
+ print("Missing configuration file: %s" % (conffile))
+ sys.exit(1)
+
+ conf = toml.load(conffile)
+ if args.list_machines:
+ print("Machines:", *list(sorted(conf.keys())), sep="\n\t")
+ sys.exit(0)
+
+ if not args.machine:
+ print("Machine name required")
+ sys.exit(1)
+
+ mach = conf[args.machine]
+ console = mach["console"]
+ conn = init_telnet(console["host"], console["port"])
+
+ try:
+ conn.encode_and_write()
+ i, m, d = conn.expect_or_raise([
+ "%s login:" % (mach["platform"]),
+ "root@%s:.*#" % (mach["platform"]),
+ "ast#",
+ ], 5)
+
+ if i != 2:
+ if i == 0:
+ conn.encode_and_write(mach["user"])
+ conn.read_until(b"Password:")
+ conn.encode_and_write(mach["password"])
+ conn.expect_or_raise(["root@%s:.*#" % (mach["platform"])])
+
+ conn.encode_and_write("reboot")
+
+ conn.expect_or_raise(["Hit any key to stop autoboot"])
+ conn.encode_and_write()
+
+ for comm in mach["u-boot"]["commands"]:
+ conn.encode_and_write(comm)
+ if "tftp" in comm:
+ i, m, d = conn.expect_or_raise([
+ r"Bytes transferred = \d+ \([0-9a-f]+ hex\)",
+ "Not retrying...",
+ r"## Warning:",
+ r"[*]{3} ERROR:",
+ "Abort",
+ ])
+ if i > 0:
+ print("Error detected, exiting", file=sys.stderr)
+ return
+
+ if args.initramfs:
+ conn.encode_and_write("setenv bootargs console=ttyS4,115200n root=/dev/ram rw earlyprintk debug")
+ conn.read_until(b"ast#")
+ else:
+ conn.encode_and_write("printenv set_bootargs")
+ i, m, d = conn.expect_or_raise([
+ "set_bootargs=.*$",
+ "## Error: \"set_bootargs\" not defined",
+ ], 1)
+ if i == 0:
+ conn.encode_and_write("run set_bootargs")
+ conn.read_until(b"ast#")
+
+ conn.encode_and_write("bootm")
+ conn.read_until(b"Starting kernel")
+ finally:
+ conn.close()
+
+if __name__ == "__main__":
+ main()
diff --git a/amboar/obmc-scripts/reboot/petitboot.exp b/amboar/obmc-scripts/reboot/petitboot.exp
new file mode 100644
index 0000000..da51dae
--- /dev/null
+++ b/amboar/obmc-scripts/reboot/petitboot.exp
@@ -0,0 +1,12 @@
+#!/usr/bin/expect -df --
+
+set timeout 300
+
+spawn ssh -p2200 {*}[lrange $argv 0 end]
+
+expect {
+ -ex "Petitboot" { exit }
+ timeout { exit 1 }
+ eof { exit 2 }
+ .* { exp_continue }
+}
diff --git a/amboar/obmc-scripts/reboot/reboot.sh b/amboar/obmc-scripts/reboot/reboot.sh
new file mode 100755
index 0000000..5b035e7
--- /dev/null
+++ b/amboar/obmc-scripts/reboot/reboot.sh
@@ -0,0 +1,21 @@
+#!/bin/bash -x
+
+set -euo pipefail
+
+CONNECT="$@"
+
+i=0
+
+while true;
+do
+ echo Boot $i
+
+ ssh ${CONNECT} /usr/sbin/obmcutil poweron
+ time expect petitboot.exp -- ${CONNECT}
+ ssh ${CONNECT} /usr/sbin/obmcutil poweroff
+
+ i=$(($i + 1))
+
+ echo
+done
+