Skip to content

Instantly share code, notes, and snippets.

@halmartin
Last active June 3, 2020 12:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save halmartin/095a185c9bad2440cf2ce2aec0a5ec68 to your computer and use it in GitHub Desktop.
Save halmartin/095a185c9bad2440cf2ce2aec0a5ec68 to your computer and use it in GitHub Desktop.
Automate (re)booting a HostSailor instance
#!/usr/bin/env python3
# Copyright (C) 2020 Hal Martin
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Tired of getting the following email from HostSailor?
# We have shutdown your Sailor KVM. with IP X.X.X.X to protect the performance of the server you're hosted on,
# due to high I/O or high CPU load this action was taken to make sure we keep our servers stable as possible.
#
# Now you can automate (re)starting your instances! Just enter your HostSailor credentials and the IP address
# of the instance you wish to boot.
#
# It "works for me(TM)" but may blow up horribly. The kludge you do for "bargain" hosting providers ¯\_(ツ)_/¯
import logging
import requests
import re
from os import getenv
LOGGING_FORMAT = getenv("LOGGING_FORMAT", '%(levelname)s - %(name)s - %(funcName)s - %(message)s')
logging.basicConfig(level=logging.DEBUG, format=LOGGING_FORMAT)
logger = logging.getLogger(__name__)
sess = requests.Session()
def boot_instance(username, password, ipaddr):
login_page = sess.get("https://clients.hostsailor.com/clientarea.php")
if login_page.status_code != 200:
logger.error("Unable to fetch login page")
return
# get the token from the login page HTML
token = re.search('token" value="\w+"', login_page.text).group(0).split('"')[-2:][:1][0]
login_resp = sess.post("https://clients.hostsailor.com/dologin.php", data={"token": token, "username": username, "password": password})
if login_resp.status_code != 200:
logger.error("Unable to login")
return
logger.info(f"Logged in as {username}")
services = sess.get("https://clients.hostsailor.com/clientarea.php?action=services")
if services.status_code != 200:
logger.error("Unable to get list of services")
return
logger.info("Got services: {}".format(services))
# get the ID of all the servers
servers = [x.split("=")[1] for x in list(set(re.findall("id=\d{5,6}", services.text)))]
for server in servers:
server_status = sess.get(f"https://clients.hostsailor.com/clientarea.php?action=productdetails&id={server}")
if server_status.status_code != 200:
logger.error(f"Unable to get status for server {server}")
logger.info(f"Got status for server {server}")
if re.search(re.escape(ipaddr), server_status.text):
# we are operating on the server we want
res = sess.get("https://clients.hostsailor.com/clientarea.php",
params={"action": "productdetails", "id": server, "serveraction": "custom", "a": "boot"})
if res.status_code == 200:
logging.info("Booted server {}".format(ipaddr))
else:
logging.info("Error booting server {}".format(ipaddr))
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='Boot a VM through the HostSailor client area')
parser.add_argument('-u', dest='username', type=str, required=True, help='HostSailor username')
parser.add_argument('-p', dest='password', type=str, required=True, help='HostSailor password')
parser.add_argument('-i', dest='ip_addr', type=str, required=True, help='Instance IP address')
args = parser.parse_args()
boot_instance(args.username, args.password, args.ip_addr)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment