dockge-cli/dockge_cli/service/connection.py

174 lines
4.7 KiB
Python
Raw Normal View History

2024-07-02 16:09:56 +00:00
import time
from typing import Any
import socketio
import socketio.exceptions
from . import storage
class DockgeConnection:
2024-07-05 14:05:35 +00:00
"""
Provider class for Dockge
Provides all the functionality for connecting, logging in and executing commands
"""
2024-07-02 16:09:56 +00:00
class LoginException(BaseException):
2024-07-05 14:05:35 +00:00
"""
Special exception when login fails too often
"""
2024-07-02 16:09:56 +00:00
_sio: socketio.Client
_host: str
_logged_in: bool
_stacklist: Any
def __init__(self):
self._logged_in = False
self._host = storage.get("host")
2024-07-03 18:36:22 +00:00
if self._host is None:
raise ValueError("Host for Dockge is not defined!")
2024-07-02 16:09:56 +00:00
self._sio = socketio.Client(logger=False, engineio_logger=False)
self._stacklist = None
self._init_events()
def _init_events(self):
@self._sio.event
def connect():
2024-07-05 22:16:41 +00:00
self.login()
2024-07-02 16:09:56 +00:00
print("Connected!")
@self._sio.event
def disconnect():
self._logged_in = False
print("Disconnected!")
@self._sio.event
def connect_error(data):
print("The connection failed!")
print(data)
@self._sio.on('info')
def info(data):
if all(k in data for k in ("version", "latestVersion", "isContainer", "primaryHostname")):
print(f"Dockge Version: {data['version']}")
@self._sio.on('agent')
def agent(*args):
if args[0] == "stackList":
self._stacklist = args[1]
# Callbacks
def _login_process(self, data):
success = False
if "ok" in data and "token" in data:
print(f"Login was {'successful' if data['ok'] else 'unsuccessful'}!")
success = True
else:
print("Issue with login procedure")
2024-07-20 15:49:25 +00:00
print(data)
2024-07-02 16:09:56 +00:00
return success
# Functions
def connect_and_login(self):
2024-07-05 14:05:35 +00:00
"""
Connect to the websocket
"""
2024-07-05 22:16:41 +00:00
# Dockge uses Socket.io for the websockets, so this URI and params are always the same
2024-10-01 21:24:31 +00:00
self._sio.connect(f"https://{self._host}/socket.io/")
2024-07-05 22:16:41 +00:00
self.login()
2024-07-02 16:09:56 +00:00
2024-07-05 22:16:41 +00:00
def login(self):
2024-07-05 14:05:35 +00:00
"""
Log into dockge using basicauth
Retries 5 times when timeouts occur
"""
2024-07-02 16:09:56 +00:00
if self._logged_in:
return
data = None
retry, count = True, 0
2024-07-05 22:16:41 +00:00
if not storage.exists("username"):
raise ValueError("Missing username")
if not storage.exists("password"):
raise ValueError("Missing password")
2024-07-02 16:09:56 +00:00
while retry and count < 5:
try:
data = self._sio.call(
"login",
{
"username": storage.get("username", encoded=True),
"password": storage.get("password", encoded=True),
2024-07-05 22:16:41 +00:00
"token": ""
2024-07-02 16:09:56 +00:00
},
2024-07-20 15:25:34 +00:00
timeout=10
2024-07-02 16:09:56 +00:00
)
retry = False
except socketio.exceptions.TimeoutError:
2024-07-20 15:25:34 +00:00
print("Reached timeout for login, retrying ...")
2024-07-02 16:09:56 +00:00
retry = True
count += 1
if retry or not self._login_process(data):
raise self.LoginException
self._logged_in = True
def list_stacks(self):
2024-07-05 14:05:35 +00:00
"""
Requests stack list from dockge, returns list when event was sent
"""
2024-07-02 16:09:56 +00:00
self._sio.emit("agent", ("", "requestStackList"))
while self._stacklist is None:
time.sleep(0.5)
retval = self._stacklist
self._stacklist = None
return retval
def list_stack(self, name: str):
2024-07-05 14:05:35 +00:00
"""
Lists status for a stack
"""
2024-07-20 15:25:34 +00:00
ret = self._sio.call("agent", ("", "serviceStatusList", name), timeout=10)
2024-07-02 16:09:56 +00:00
return ret
def restart(self, name):
2024-07-05 14:05:35 +00:00
"""
Restarts a given stack
"""
2024-07-20 15:25:34 +00:00
ret = self._sio.call("agent", ("", "restartStack", name), timeout=30)
2024-07-02 16:09:56 +00:00
return ret
2024-07-03 18:36:22 +00:00
2024-07-02 19:45:56 +00:00
def update(self, name):
2024-07-05 14:05:35 +00:00
"""
Updates a given stack
"""
2024-07-20 15:25:34 +00:00
ret = self._sio.call("agent", ("", "updateStack", name), timeout=30)
2024-07-02 19:45:56 +00:00
return ret
2024-07-03 18:36:22 +00:00
2024-07-02 19:45:56 +00:00
def stop(self, name):
2024-07-05 14:05:35 +00:00
"""
Stops a given stack
"""
2024-07-20 15:25:34 +00:00
ret = self._sio.call("agent", ("", "stopStack", name), timeout=30)
2024-07-02 19:45:56 +00:00
return ret
2024-07-03 18:36:22 +00:00
2024-07-02 19:45:56 +00:00
def start(self, name):
2024-07-05 14:05:35 +00:00
"""
Starts a given stack
"""
2024-07-20 15:25:34 +00:00
ret = self._sio.call("agent", ("", "startStack", name), timeout=30)
2024-07-02 19:45:56 +00:00
return ret
2024-07-03 18:36:22 +00:00
2024-07-02 19:45:56 +00:00
def down(self, name):
2024-07-05 14:05:35 +00:00
"""
Stops and downs a given stack
"""
2024-07-20 15:25:34 +00:00
ret = self._sio.call("agent", ("", "downStack", name), timeout=30)
2024-07-02 19:45:56 +00:00
return ret
2024-07-02 16:09:56 +00:00
def disconnect(self):
2024-07-05 14:05:35 +00:00
"""
Logs out of dockge
"""
2024-07-02 16:09:56 +00:00
self._sio.emit("logout")
self._sio.disconnect()