blob: 8032ea54f8b6f9f9a0dc5708f697165768e43c8c [file] [log] [blame]
Andrew Jeffery75d9c242017-09-27 23:08:56 +09301#!/usr/bin/env python3
2
3import argparse
4import sys
5import time
6import toml
7from os import path
8from telnetlib import Telnet
9from types import MethodType
10from xdg import BaseDirectory
11
12def expect_or_raise(conn, patterns, timeout=None):
13 i, m, d = conn.expect([bytes(p, 'ascii') for p in patterns], timeout)
14 if i == -1:
15 msg = "Match failed, expected '%s', got '%s'" % (str(patterns), d)
16 print(msg, file=sys.stderr)
17 raise ValueError
18 return i, m, d
19
20def encode_and_write(conn, comm="", sep="\n"):
21 # Slow down the writes to help poor ol' serial-over-telnet
22 for c in comm + sep:
23 conn.write(bytes(c, 'ascii'))
24 time.sleep(0.01)
25
26def init_telnet(host, port=0, timeout=None):
27 conn = Telnet(host, port, timeout)
28 conn.encode_and_write = MethodType(encode_and_write, conn)
29 conn.expect_or_raise = MethodType(expect_or_raise, conn)
30 return conn
31
32
33def main():
34 parser = argparse.ArgumentParser()
Andrew Jeffery49b35be2017-09-28 10:32:20 +093035 parser.add_argument("machine", nargs="?")
36 parser.add_argument("-l", "--list-machines", action="store_true")
Andrew Jeffery291f0812017-10-07 00:52:56 +103037 parser.add_argument("-i", "--initramfs", action="store_true")
Andrew Jeffery75d9c242017-09-27 23:08:56 +093038 args = parser.parse_args()
39
40 confbase = BaseDirectory.save_config_path("obmc-scripts")
41 conffile = path.join(confbase, "netboot")
42 if not path.exists(conffile):
43 print("Missing configuration file: %s" % (conffile))
44 sys.exit(1)
45
46 conf = toml.load(conffile)
Andrew Jeffery49b35be2017-09-28 10:32:20 +093047 if args.list_machines:
48 print("Machines:", *list(sorted(conf.keys())), sep="\n\t")
49 sys.exit(0)
50
51 if not args.machine:
52 print("Machine name required")
53 sys.exit(1)
54
Andrew Jeffery75d9c242017-09-27 23:08:56 +093055 mach = conf[args.machine]
56 console = mach["console"]
57 conn = init_telnet(console["host"], console["port"])
58
59 try:
60 conn.encode_and_write()
61 i, m, d = conn.expect_or_raise([
62 "%s login:" % (mach["platform"]),
63 "root@%s:.*#" % (mach["platform"]),
Andrew Jefferyac475772018-02-02 17:47:24 +103064 "root@%s:.*#" % (args.machine),
Andrew Jeffery75d9c242017-09-27 23:08:56 +093065 "ast#",
Andrew Jefferyac475772018-02-02 17:47:24 +103066 "# ",
Andrew Jeffery75d9c242017-09-27 23:08:56 +093067 ], 5)
68
Andrew Jefferyac475772018-02-02 17:47:24 +103069 if i != 3:
Andrew Jeffery75d9c242017-09-27 23:08:56 +093070 if i == 0:
71 conn.encode_and_write(mach["user"])
72 conn.read_until(b"Password:")
73 conn.encode_and_write(mach["password"])
74 conn.expect_or_raise(["root@%s:.*#" % (mach["platform"])])
75
76 conn.encode_and_write("reboot")
77
78 conn.expect_or_raise(["Hit any key to stop autoboot"])
79 conn.encode_and_write()
80
81 for comm in mach["u-boot"]["commands"]:
82 conn.encode_and_write(comm)
83 if "tftp" in comm:
84 i, m, d = conn.expect_or_raise([
85 r"Bytes transferred = \d+ \([0-9a-f]+ hex\)",
86 "Not retrying...",
Andrew Jefferye4bf3362017-09-28 10:32:05 +093087 r"## Warning:",
Andrew Jeffery75d9c242017-09-27 23:08:56 +093088 r"[*]{3} ERROR:",
Andrew Jeffery291f0812017-10-07 00:52:56 +103089 "Abort",
Andrew Jeffery8b0dacb2018-02-19 13:41:18 +103090 "Retry count exceeded; starting again",
Andrew Jeffery75d9c242017-09-27 23:08:56 +093091 ])
Andrew Jefferye4bf3362017-09-28 10:32:05 +093092 if i > 0:
Andrew Jeffery75d9c242017-09-27 23:08:56 +093093 print("Error detected, exiting", file=sys.stderr)
94 return
95
Andrew Jeffery291f0812017-10-07 00:52:56 +103096 if args.initramfs:
97 conn.encode_and_write("setenv bootargs console=ttyS4,115200n root=/dev/ram rw earlyprintk debug")
Andrew Jeffery75d9c242017-09-27 23:08:56 +093098 conn.read_until(b"ast#")
Andrew Jeffery291f0812017-10-07 00:52:56 +103099 else:
100 conn.encode_and_write("printenv set_bootargs")
101 i, m, d = conn.expect_or_raise([
102 "set_bootargs=.*$",
103 "## Error: \"set_bootargs\" not defined",
104 ], 1)
105 if i == 0:
106 conn.encode_and_write("run set_bootargs")
107 conn.read_until(b"ast#")
Andrew Jeffery75d9c242017-09-27 23:08:56 +0930108
109 conn.encode_and_write("bootm")
110 conn.read_until(b"Starting kernel")
111 finally:
112 conn.close()
113
114if __name__ == "__main__":
115 main()