GPIO export dance
[libremanage.git] / libremanage.py
CommitLineData
3f7ab73a
AR
1"""
2libremanage - Lightweight, free software for remote side-chanel server management
3
4Copyright (C) 2018 Alyssa Rosenzweig
5
6This program is free software: you can redistribute it and/or modify
7it under the terms of the GNU Affero General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Affero General Public License for more details.
15
16You should have received a copy of the GNU Affero General Public License
17along with this program. If not, see <https://www.gnu.org/licenses/>.
18"""
93f19e92
AR
19
20import sys
61110684 21import json
d8ddde1a 22import functools
b2b1b982 23import subprocess
93f19e92 24
b266c229 25USAGE = """
93f19e92
AR
26Usage:
27
28 $ libremanage [server name] [command]
29
30Example:
31
32 $ libremanage web2 reboot
33
34Server names are defined in the accompanying config.py.
35
36Valid commands are as follows:
37
38 - shutdown, reboot, poweron: Power management
9ed4bf16 39 - tty: Open TTY in GNU Screen
93f19e92
AR
40"""
41
61110684
AR
42with open("config.json") as f:
43 CONFIG = json.load(f)
e14c36b3 44
28c204f9
AR
45def open_ssh(server, command):
46 config = server["ssh"]
da2eb513 47 subprocess.run(["ssh", config["username"] + "@" + config["host"], "-p", str(config["port"]), command])
e14c36b3 48
40a688c0
AR
49def die_with_usage(message):
50 print(message)
b266c229
AR
51 print(USAGE)
52 sys.exit(1)
53
40a688c0
AR
54if len(sys.argv) != 3:
55 die_with_usage("Incorrect number of arguments")
56
d8ddde1a 57def get_server_handle(name):
82ee0c31
AR
58 server = CONFIG["servers"][name]
59 server["ssh"] = CONFIG["managers"][server["manager"]]
60 return server
d8ddde1a
AR
61
62def set_server_power(state, server):
20249149 63 print("Setting to power state " + str(state))
e799dcd1
AR
64 conf = server["power"]
65
66 # Set invert to write LOW for power on and HIGH for off
67 if conf["invert"]:
68 state = 1 - state
69
70 print(conf["pin"])
282c96f8
AR
71
72 # Export pin, write value, unexport
73 open_ssh(server, "echo " + str(conf["pin"]) + " > /sys/class/gpio/export")
74 open_ssh(server, "cat /sys/class/gpio/gpio" + str(conf["pin"]) + "/value")
75 open_ssh(server, "echo " + str(conf["pin"]) + " > /sys/class/gpio/unexport")
d8ddde1a
AR
76
77COMMANDS = {
e14d7650
AR
78 # Power managemment
79
da2eb513
AR
80 "shutdown": functools.partial(set_server_power, 0),
81 "poweron": functools.partial(set_server_power, 1),
82 "reboot": lambda s: (set_server_power(0, s), set_server_power(1, s)),
e14d7650
AR
83
84 # TTY access (or keyboard if wired as such)
85
f0ccad0a 86 "tty": lambda s: open_ssh(s, "screen " + s["tty"]["file"] + str(s["tty"]["baud"])),
e14c36b3 87
da2eb513 88 # SSH sanity tests
82ee0c31 89
28c204f9
AR
90 "sanity": lambda s: open_ssh(s, "whoami"),
91 "console": lambda s: open_ssh(s, ""),
d8ddde1a
AR
92}
93
d24528e4 94def issue_command(server_name, command):
d8ddde1a 95 server = get_server_handle(server_name)
d24528e4 96 print(server_name, command)
40a688c0
AR
97
98 try:
da2eb513 99 callback = COMMANDS[command]
40a688c0
AR
100 except KeyError:
101 die_with_usage("Invalid command supplied")
d24528e4 102
82ee0c31 103 callback(server)
e14d7650 104
d24528e4 105issue_command(sys.argv[1], sys.argv[2])