Created
January 27, 2025 17:57
-
-
Save sirtaj/4d82436c26a63152a71ba282d701aa94 to your computer and use it in GitHub Desktop.
Shutdown or suspend a linux system via HTTP GET or POST.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# WARNING: Don't use it on any system you care about. | |
# A super-simple linux implementation of this windows shutdown service: | |
# https://github.com/karpach/remote-shutdown-pc | |
# This makes it turn off/suspend from home assistant using rest_command. | |
import http.server | |
import socketserver | |
import os | |
import json | |
PORT = 5001 | |
VALID_PIN = int( | |
os.environ.get("REST_SHUTDOWN_PIN", XXX) | |
) # Get PIN from environment variable | |
class RequestHandler(http.server.SimpleHTTPRequestHandler): | |
def do_GET(self): | |
# Extract the PIN from the URL path | |
path_parts = self.path.strip("/").split("/") | |
if len(path_parts) != 2: | |
self.send_response(400) | |
self.end_headers() | |
self.wfile.write( | |
b'Invalid URL format. Use "<PIN>/suspend" or "<PIN>/shutdown".' | |
) | |
return | |
pin = path_parts[0] | |
action = path_parts[1] | |
if int(pin) != VALID_PIN: | |
self.send_response(403) # Forbidden | |
self.end_headers() | |
self.wfile.write(b"Unauthorized: Invalid PIN.") | |
return | |
if action == "shutdown": | |
code = 200 | |
response = "Shutting down" | |
try: | |
os.system("sudo -n shutdown now") | |
except Exception(e): | |
code = 500 | |
response = str(e) | |
self.send_response(code) | |
self.end_headers() | |
self.wfile.write(response.encode("utf-8")) | |
elif action == "suspend": | |
code = 200 | |
response = "Suspending" | |
try: | |
os.system("sudo -n systemctl suspend") | |
except Exception(e): | |
code = 500 | |
response = str(e) | |
self.send_response(code) | |
self.end_headers() | |
self.wfile.write(response.encode("utf-8")) | |
else: | |
self.send_response(400) | |
self.end_headers() | |
self.wfile.write(b'Invalid action. Use "shutdown" or "suspend".') | |
do_POST = do_GET | |
def run(server_class=http.server.HTTPServer, handler_class=RequestHandler): | |
with socketserver.TCPServer(("", PORT), handler_class) as httpd: | |
print(f"Serving on port {PORT}") | |
httpd.serve_forever() | |
if __name__ == "__main__": | |
run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment