Skip to content
This repository has been archived by the owner on Mar 19, 2024. It is now read-only.

Write connection details to TTY on boot #53

Merged
merged 19 commits into from
Jul 27, 2020
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions stage2/01-sys-tweaks/files/rc.local
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,12 @@ if [ ! -f /home/umbrel/statuses/service-configured ]; then
fi
fi

# Display connection details on the TTY
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could add a clear here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we should clear the TTY here since there could be useful log output on the screen that we don't want to overwrite.

if command -v connection-details > /dev/null; then
lukechilds marked this conversation as resolved.
Show resolved Hide resolved
# We run this in the background because it waits for the Tor hidden service
# to be created on first boot. rc.local needs to exit so the boot process
# can continue.
connection-details &
fi

exit 0
1 change: 1 addition & 0 deletions stage2/06-connection-details/00-packages
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pipenv
14 changes: 14 additions & 0 deletions stage2/06-connection-details/01-run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash -e

echo "Installing connection-details and dependencies"

cp files/Pipfile* ${ROOTFS_DIR}/
lukechilds marked this conversation as resolved.
Show resolved Hide resolved

on_chroot << EOF
PIPENV_PIPFILE="/Pipfile" pipenv --python "$(which python3)" install --system
EOF

rm ${ROOTFS_DIR}/Pipfile*
lukechilds marked this conversation as resolved.
Show resolved Hide resolved

chmod +x files/connection-details
cp files/connection-details ${ROOTFS_DIR}/usr/local/bin/connection-details
12 changes: 12 additions & 0 deletions stage2/06-connection-details/files/Pipfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
qrcode = "6.1"

[requires]
python_version = "3.8"
37 changes: 37 additions & 0 deletions stage2/06-connection-details/files/Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

109 changes: 109 additions & 0 deletions stage2/06-connection-details/files/connection-details
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/env python3

import sys
import os
import time
import subprocess
from io import TextIOWrapper, BytesIO
import qrcode

umbrel_ascii = '''
,;###GGGGGGGGGGl#Sp
,##GGGlW""^' '`""%GGGG#S,
,#GGG" "lGG#o
#GGl^ '$GG#
,#GGb \GGG,
lGG" "GGG
#GGGlGGGl##p,,p##lGGl##p,,p###ll##GGGG
!GGGlW"""*GGGGGGG#""""WlGGGGG#W""*WGGGGS
"" "^ '" ""


@GGS lG#
!GGG !GGG
!GGG !GGG
!GGG !GGG
!GGG !GGG
!GGG !GGG
'GGG $GGl
"GGG#psqp##GG#
"%GGGGGG#"
'''.strip('\n')

def create_qr(data):
output_buffer = TextIOWrapper(BytesIO(), sys.stdout.encoding)

qr = qrcode.QRCode(border=0, error_correction=qrcode.constants.ERROR_CORRECT_Q)
qr.add_data(data)
qr.print_ascii(out=output_buffer)

output_buffer.seek(0)
qr_ascii = output_buffer.read().strip()

return qr_ascii

def combine_ascii(left_ascii, right_ascii, spacing=0):
left_lines = left_ascii.split('\n')
right_lines = right_ascii.split('\n')

no_left_lines = len(left_lines)
no_right_lines = len(right_lines)

left_width = max(list(map(lambda line: len(line), left_lines)))
max_height = max(no_left_lines, no_right_lines)

lines = []
for i in range(max_height):
left_line = left_lines[i] if i < no_left_lines else ""
right_line = right_lines[i] if i < no_right_lines else ""

padding = " " * ((left_width - len(left_line)) + spacing)

lines.append(left_line + padding + right_line)

return "\n".join(lines)

def read_file_when_available(file_path, timeout):
start = time.time()
while not os.path.exists(file_path):
if (time.time() - start) > timeout:
return False
time.sleep(1)

with open(file_path, "r") as file:
file_contents = file.read()

return file_contents

def run(command):
result = subprocess.run(command, stdout=subprocess.PIPE)
return result.stdout.decode('utf-8').rstrip("\n")

def main():
timeout = 30
tor_hostname_file = "/home/umbrel/tor/data/web/hostname"
tor_hostname = read_file_when_available(tor_hostname_file, timeout)

if not tor_hostname:
print("Couldn't get connection details")
return

tor_hostname_qr_ascii = create_qr(tor_hostname.strip())
ascii_banner = combine_ascii(umbrel_ascii, tor_hostname_qr_ascii, spacing=10)

ip = run(['hostname', '-I']).split(" ")[0]

connection_details = f"""


{ascii_banner}

Your Umbrel is up and running at:

http://umbrel.local
http://{ip}
http://{tor_hostname}
"""
print(connection_details)

main()