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"
|
||||
remoteHost = "billysballoons.com"
|
||||
sasUser = "sas"
|
||||
sshdService = "sshd"
|
||||
pingIntervalSeconds = 180
|
||||
pingCount = 5
|
||||
maxWormholeFailures = 3
|
||||
@@ -97,6 +98,32 @@ def run_as_user(userName, command, useSpeech, check=True):
|
||||
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):
|
||||
result = run_command(["getent", "passwd", userName])
|
||||
return result.returncode == 0
|
||||
@@ -351,13 +378,14 @@ def main():
|
||||
tempDir = tempfile.mkdtemp(prefix="sas-ii-")
|
||||
ircSession = None
|
||||
sshProcess = None
|
||||
sshdWasActiveAtStart = service_is_active(sshdService)
|
||||
shouldStopSshdOnCleanup = False
|
||||
|
||||
def cleanup(exitMessage=None):
|
||||
nonlocal cleanupDone
|
||||
nonlocal cleanupDone, sshProcess
|
||||
if cleanupDone:
|
||||
return
|
||||
cleanupDone = True
|
||||
nonlocal sshProcess
|
||||
if exitMessage:
|
||||
say_or_print(exitMessage, useSpeech)
|
||||
|
||||
@@ -371,6 +399,20 @@ def main():
|
||||
if ircSession:
|
||||
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:
|
||||
try:
|
||||
run_privileged(["pkill", "-u", sasUser], useSpeech, check=False)
|
||||
@@ -398,10 +440,24 @@ def main():
|
||||
cleanup("Interrupted. Cleaning up.")
|
||||
sys.exit(1)
|
||||
|
||||
signal.signal(signal.SIGINT, handle_signal)
|
||||
signal.signal(signal.SIGTERM, handle_signal)
|
||||
def ensure_sshd_active():
|
||||
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:
|
||||
say_or_print("Preparing your support session.", useSpeech)
|
||||
|
||||
if not user_exists(sasUser):
|
||||
run_privileged(
|
||||
["useradd", "-m", "-d", f"/home/{sasUser}", "-s", "/bin/bash", "-G", "wheel", sasUser],
|
||||
@@ -443,7 +499,7 @@ def main():
|
||||
ircSession.start()
|
||||
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()
|
||||
nextPingTime = startTime
|
||||
pingsSent = 0
|
||||
@@ -468,11 +524,18 @@ def main():
|
||||
cleanup("No one was available to help, please try again later.")
|
||||
return 1
|
||||
|
||||
say_or_print(
|
||||
"An assistant has responded to your support request and should connect shortly.",
|
||||
useSpeech,
|
||||
)
|
||||
|
||||
ircSession.send_private_message(
|
||||
confirmedAdmin,
|
||||
f'password: "{password}" please send wormhole ssh invite code',
|
||||
)
|
||||
|
||||
say_or_print("Exchanging secure connection information. This may take a moment.", useSpeech)
|
||||
|
||||
failures = 0
|
||||
while failures < maxWormholeFailures:
|
||||
inviteCode = None
|
||||
@@ -500,6 +563,11 @@ def main():
|
||||
say_or_print("Wormhole key transfer succeeded.", useSpeech)
|
||||
break
|
||||
|
||||
say_or_print(
|
||||
"That connection code did not work. Waiting for a new code from the assistant.",
|
||||
useSpeech,
|
||||
)
|
||||
|
||||
failures += 1
|
||||
errorTextFull = (result.stderr or result.stdout or "").strip()
|
||||
if errorTextFull and not useSpeech:
|
||||
@@ -523,6 +591,8 @@ def main():
|
||||
cleanup("Wormhole failed too many times. Exiting.")
|
||||
return 1
|
||||
|
||||
ensure_sshd_active()
|
||||
|
||||
say_or_print("Starting reverse SSH tunnel. Press Ctrl+C to stop.", useSpeech)
|
||||
sshCommand = [
|
||||
"ssh",
|
||||
@@ -548,6 +618,7 @@ def main():
|
||||
sshCommand = ["sudo", "-u", sasUser, "-H"] + sshCommand
|
||||
sshProcess = subprocess.Popen(sshCommand)
|
||||
sshProcess.wait()
|
||||
say_or_print("The support connection ended. Cleaning up.", useSpeech)
|
||||
|
||||
except Exception as exc:
|
||||
cleanup(f"Error: {exc}")
|
||||
|
||||
Reference in New Issue
Block a user