Insure that sshd is started. Provide more helpful messages through out the process for the person receiving assistance.
This commit is contained in:
@@ -19,6 +19,7 @@ ircPort = 6667
|
|||||||
ircChannel = "#stormux"
|
ircChannel = "#stormux"
|
||||||
remoteHost = "billysballoons.com"
|
remoteHost = "billysballoons.com"
|
||||||
sasUser = "sas"
|
sasUser = "sas"
|
||||||
|
sshdService = "sshd"
|
||||||
pingIntervalSeconds = 180
|
pingIntervalSeconds = 180
|
||||||
pingCount = 5
|
pingCount = 5
|
||||||
maxWormholeFailures = 3
|
maxWormholeFailures = 3
|
||||||
@@ -97,6 +98,32 @@ def run_as_user(userName, command, useSpeech, check=True):
|
|||||||
return run_command(fullCommand, check=check)
|
return run_command(fullCommand, check=check)
|
||||||
|
|
||||||
|
|
||||||
|
def command_error_text(result):
|
||||||
|
return (result.stderr or result.stdout or "").strip()
|
||||||
|
|
||||||
|
|
||||||
|
def service_is_active(serviceName):
|
||||||
|
result = run_command(["systemctl", "is-active", "--quiet", serviceName])
|
||||||
|
return result.returncode == 0
|
||||||
|
|
||||||
|
|
||||||
|
def start_service(serviceName, useSpeech):
|
||||||
|
result = run_privileged(["systemctl", "start", serviceName], useSpeech, check=False)
|
||||||
|
if result.returncode == 0:
|
||||||
|
return
|
||||||
|
errorText = command_error_text(result)
|
||||||
|
if errorText:
|
||||||
|
raise RuntimeError(f"Failed to start {serviceName}: {errorText}")
|
||||||
|
raise RuntimeError(f"Failed to start {serviceName}")
|
||||||
|
|
||||||
|
|
||||||
|
def stop_service(serviceName, useSpeech):
|
||||||
|
result = run_privileged(["systemctl", "stop", serviceName], useSpeech, check=False)
|
||||||
|
if result.returncode == 0:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def user_exists(userName):
|
def user_exists(userName):
|
||||||
result = run_command(["getent", "passwd", userName])
|
result = run_command(["getent", "passwd", userName])
|
||||||
return result.returncode == 0
|
return result.returncode == 0
|
||||||
@@ -351,13 +378,14 @@ def main():
|
|||||||
tempDir = tempfile.mkdtemp(prefix="sas-ii-")
|
tempDir = tempfile.mkdtemp(prefix="sas-ii-")
|
||||||
ircSession = None
|
ircSession = None
|
||||||
sshProcess = None
|
sshProcess = None
|
||||||
|
sshdWasActiveAtStart = service_is_active(sshdService)
|
||||||
|
shouldStopSshdOnCleanup = False
|
||||||
|
|
||||||
def cleanup(exitMessage=None):
|
def cleanup(exitMessage=None):
|
||||||
nonlocal cleanupDone
|
nonlocal cleanupDone, sshProcess
|
||||||
if cleanupDone:
|
if cleanupDone:
|
||||||
return
|
return
|
||||||
cleanupDone = True
|
cleanupDone = True
|
||||||
nonlocal sshProcess
|
|
||||||
if exitMessage:
|
if exitMessage:
|
||||||
say_or_print(exitMessage, useSpeech)
|
say_or_print(exitMessage, useSpeech)
|
||||||
|
|
||||||
@@ -371,6 +399,20 @@ def main():
|
|||||||
if ircSession:
|
if ircSession:
|
||||||
ircSession.stop()
|
ircSession.stop()
|
||||||
|
|
||||||
|
if shouldStopSshdOnCleanup:
|
||||||
|
say_or_print("Stopping sshd; it was not active when sas started.", useSpeech)
|
||||||
|
try:
|
||||||
|
if not stop_service(sshdService, useSpeech):
|
||||||
|
say_or_print(
|
||||||
|
"Cleanup warning: failed to stop sshd. Please stop it manually.",
|
||||||
|
useSpeech,
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
say_or_print(
|
||||||
|
"Cleanup warning: failed to stop sshd. Please stop it manually.",
|
||||||
|
useSpeech,
|
||||||
|
)
|
||||||
|
|
||||||
if shouldRemoveUser:
|
if shouldRemoveUser:
|
||||||
try:
|
try:
|
||||||
run_privileged(["pkill", "-u", sasUser], useSpeech, check=False)
|
run_privileged(["pkill", "-u", sasUser], useSpeech, check=False)
|
||||||
@@ -398,10 +440,24 @@ def main():
|
|||||||
cleanup("Interrupted. Cleaning up.")
|
cleanup("Interrupted. Cleaning up.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, handle_signal)
|
def ensure_sshd_active():
|
||||||
signal.signal(signal.SIGTERM, handle_signal)
|
nonlocal shouldStopSshdOnCleanup
|
||||||
|
if service_is_active(sshdService):
|
||||||
|
shouldStopSshdOnCleanup = not sshdWasActiveAtStart
|
||||||
|
return
|
||||||
|
say_or_print("Starting sshd for this support session.", useSpeech)
|
||||||
|
start_service(sshdService, useSpeech)
|
||||||
|
if not service_is_active(sshdService):
|
||||||
|
raise RuntimeError("sshd did not become active")
|
||||||
|
shouldStopSshdOnCleanup = not sshdWasActiveAtStart
|
||||||
|
|
||||||
|
for signalName in ("SIGINT", "SIGTERM", "SIGHUP", "SIGQUIT"):
|
||||||
|
if hasattr(signal, signalName):
|
||||||
|
signal.signal(getattr(signal, signalName), handle_signal)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
say_or_print("Preparing your support session.", useSpeech)
|
||||||
|
|
||||||
if not user_exists(sasUser):
|
if not user_exists(sasUser):
|
||||||
run_privileged(
|
run_privileged(
|
||||||
["useradd", "-m", "-d", f"/home/{sasUser}", "-s", "/bin/bash", "-G", "wheel", sasUser],
|
["useradd", "-m", "-d", f"/home/{sasUser}", "-s", "/bin/bash", "-G", "wheel", sasUser],
|
||||||
@@ -443,7 +499,7 @@ def main():
|
|||||||
ircSession.start()
|
ircSession.start()
|
||||||
ircSession.join_channel()
|
ircSession.join_channel()
|
||||||
|
|
||||||
say_or_print("Waiting for assistance on IRC.", useSpeech)
|
say_or_print("Waiting for a Stormux assistant to respond.", useSpeech)
|
||||||
startTime = time.monotonic()
|
startTime = time.monotonic()
|
||||||
nextPingTime = startTime
|
nextPingTime = startTime
|
||||||
pingsSent = 0
|
pingsSent = 0
|
||||||
@@ -468,11 +524,18 @@ def main():
|
|||||||
cleanup("No one was available to help, please try again later.")
|
cleanup("No one was available to help, please try again later.")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
say_or_print(
|
||||||
|
"An assistant has responded to your support request and should connect shortly.",
|
||||||
|
useSpeech,
|
||||||
|
)
|
||||||
|
|
||||||
ircSession.send_private_message(
|
ircSession.send_private_message(
|
||||||
confirmedAdmin,
|
confirmedAdmin,
|
||||||
f'password: "{password}" please send wormhole ssh invite code',
|
f'password: "{password}" please send wormhole ssh invite code',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
say_or_print("Exchanging secure connection information. This may take a moment.", useSpeech)
|
||||||
|
|
||||||
failures = 0
|
failures = 0
|
||||||
while failures < maxWormholeFailures:
|
while failures < maxWormholeFailures:
|
||||||
inviteCode = None
|
inviteCode = None
|
||||||
@@ -500,6 +563,11 @@ def main():
|
|||||||
say_or_print("Wormhole key transfer succeeded.", useSpeech)
|
say_or_print("Wormhole key transfer succeeded.", useSpeech)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
say_or_print(
|
||||||
|
"That connection code did not work. Waiting for a new code from the assistant.",
|
||||||
|
useSpeech,
|
||||||
|
)
|
||||||
|
|
||||||
failures += 1
|
failures += 1
|
||||||
errorTextFull = (result.stderr or result.stdout or "").strip()
|
errorTextFull = (result.stderr or result.stdout or "").strip()
|
||||||
if errorTextFull and not useSpeech:
|
if errorTextFull and not useSpeech:
|
||||||
@@ -523,6 +591,8 @@ def main():
|
|||||||
cleanup("Wormhole failed too many times. Exiting.")
|
cleanup("Wormhole failed too many times. Exiting.")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
ensure_sshd_active()
|
||||||
|
|
||||||
say_or_print("Starting reverse SSH tunnel. Press Ctrl+C to stop.", useSpeech)
|
say_or_print("Starting reverse SSH tunnel. Press Ctrl+C to stop.", useSpeech)
|
||||||
sshCommand = [
|
sshCommand = [
|
||||||
"ssh",
|
"ssh",
|
||||||
@@ -548,6 +618,7 @@ def main():
|
|||||||
sshCommand = ["sudo", "-u", sasUser, "-H"] + sshCommand
|
sshCommand = ["sudo", "-u", sasUser, "-H"] + sshCommand
|
||||||
sshProcess = subprocess.Popen(sshCommand)
|
sshProcess = subprocess.Popen(sshCommand)
|
||||||
sshProcess.wait()
|
sshProcess.wait()
|
||||||
|
say_or_print("The support connection ended. Cleaning up.", useSpeech)
|
||||||
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
cleanup(f"Error: {exc}")
|
cleanup(f"Error: {exc}")
|
||||||
|
|||||||
Reference in New Issue
Block a user