replace most subprocess calls with native calls; download and install dlib from tarball instead of making git clone; configure dlib according to cpu flags; do not install opencv using pip; set use_cnn option automatically; minor code cleanup
This commit is contained in:
parent
9c2507ed13
commit
ff02a723d4
1 changed files with 84 additions and 47 deletions
131
debian/postinst
vendored
131
debian/postinst
vendored
|
|
@ -10,14 +10,13 @@ def col(id):
|
|||
return "\033[0m"
|
||||
|
||||
# Import required modules
|
||||
import fileinput
|
||||
import subprocess
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import signal
|
||||
import fileinput
|
||||
import urllib.parse
|
||||
import tarfile
|
||||
from shutil import rmtree, which
|
||||
|
||||
# Don't run unless we need to configure the install
|
||||
# Will also happen on upgrade but we will catch that later on
|
||||
|
|
@ -35,6 +34,7 @@ def handleStatus(status):
|
|||
print(col(3) + "Error while running last command" + col(0))
|
||||
sys.exit(1)
|
||||
|
||||
sc = subprocess.call
|
||||
|
||||
# We're not in fresh configuration mode so don't continue the setup
|
||||
if not os.path.exists("/tmp/howdy_picked_device"):
|
||||
|
|
@ -78,64 +78,108 @@ picked = in_file.read()
|
|||
in_file.close()
|
||||
|
||||
# Remove the temporary file
|
||||
subprocess.call(["rm /tmp/howdy_picked_device"], shell=True)
|
||||
os.unlink("/tmp/howdy_picked_device")
|
||||
|
||||
log("Upgrading pip to the latest version")
|
||||
|
||||
# Update pip
|
||||
handleStatus(subprocess.call(["pip3 install --upgrade pip"], shell=True))
|
||||
handleStatus(sc(["pip3", "install", "--upgrade", "pip"]))
|
||||
|
||||
log("Cloning dlib")
|
||||
dlib_archive = '/tmp/dlib_latest.tar.gz'
|
||||
|
||||
# Clone the dlib git to /tmp, but only the last commit
|
||||
handleStatus(subprocess.call(["git", "clone", "--depth", "1", "https://github.com/davisking/dlib.git", "/tmp/dlib_clone"]))
|
||||
log('Downloading dlib')
|
||||
|
||||
loader = which('curl')
|
||||
LOADER_CMD = None
|
||||
if loader:
|
||||
LOADER_CMD = [loader, '--silent', '--retry', '5', '--location', '--output']
|
||||
else:
|
||||
loader = which('wget')
|
||||
LOADER_CMD = [loader, '--quiet', '--tries', '5', '--output-document']
|
||||
|
||||
cmd = LOADER_CMD + [dlib_archive, 'https://api.github.com/repos/davisking/dlib/tarball/latest']
|
||||
|
||||
handleStatus(sc(cmd))
|
||||
|
||||
DLIB_DIR = None
|
||||
|
||||
excludes = re.compile(
|
||||
'davisking-dlib-\w+/(dlib/(http_client|java|matlab|test/)|'
|
||||
'(docs|examples|python_examples)|'
|
||||
'tools/(archive|convert_dlib_nets_to_caffe|htmlify|imglab|python/test|visual_studio_natvis))'
|
||||
)
|
||||
with tarfile.open(dlib_archive) as tf:
|
||||
for item in tf:
|
||||
# tarball contains directory davisking-dlib-<commit id>, so peek into archive for the name
|
||||
if not DLIB_DIR:
|
||||
DLIB_DIR = item.name
|
||||
|
||||
# extract only files sufficent for building
|
||||
if not excludes.match(item.name):
|
||||
tf.extract(item, '/tmp')
|
||||
|
||||
os.unlink(dlib_archive)
|
||||
|
||||
log("Building dlib")
|
||||
|
||||
# Start the build without GPU
|
||||
handleStatus(subprocess.call(["cd /tmp/dlib_clone/; python3 setup.py install --yes USE_AVX_INSTRUCTIONS --no DLIB_USE_CUDA"], shell=True))
|
||||
# Start the build
|
||||
cmd = ["python3", "setup.py", "install"]
|
||||
|
||||
flags = ''
|
||||
with open('/proc/cpuinfo') as info:
|
||||
for line in info:
|
||||
if 'flags' in line:
|
||||
flags = line
|
||||
break
|
||||
|
||||
if 'avx' in flags:
|
||||
cmd += ["--yes", "USE_AVX_INSTRUCTIONS"]
|
||||
elif 'sse4' in flags:
|
||||
cmd += ["--yes", "USE_SSE4_INSTRUCTIONS"]
|
||||
elif 'sse3' in flags:
|
||||
cmd += ["--yes", "USE_SSE3_INSTRUCTIONS"]
|
||||
elif 'sse2' in flags:
|
||||
cmd += ["--yes", "USE_SSE2_INSTRUCTIONS"]
|
||||
|
||||
sp = subprocess.run(cmd, cwd=DLIB_DIR, stderr=subprocess.STDOUT)
|
||||
handleStatus(sp.returncode)
|
||||
|
||||
# simple check for CUDA
|
||||
cuda_used = 'DLIB WILL USE CUDA' in sp.stdout
|
||||
|
||||
log("Cleaning up dlib")
|
||||
|
||||
# Remove the no longer needed git clone
|
||||
handleStatus(subprocess.call(["rm", "-rf", "/tmp/dlib_clone"]))
|
||||
print("Temporary dlib files removed")
|
||||
del sp
|
||||
rmtree(DLIB_DIR)
|
||||
|
||||
log("Installing python dependencies")
|
||||
log("Temporary dlib files removed")
|
||||
|
||||
# Install direct dependencies so pip does not freak out with the manual dlib install
|
||||
handleStatus(subprocess.call(["pip3", "install", "--cache-dir", "/tmp/pip_howdy", "face_recognition_models==0.3.0", "Click>=6.0", "numpy", "Pillow"]))
|
||||
|
||||
log("Installing face_recognition")
|
||||
|
||||
# Install face_recognition though pip
|
||||
handleStatus(subprocess.call(["pip3", "install", "--cache-dir", "/tmp/pip_howdy", "--no-deps", "face_recognition==1.2.2"]))
|
||||
|
||||
try:
|
||||
import cv2
|
||||
except Exception as e:
|
||||
log("Reinstalling opencv2")
|
||||
handleStatus(subprocess.call(["pip3", "install", "opencv-python"]))
|
||||
|
||||
log("Configuring howdy")
|
||||
|
||||
# Manually change the camera id to the one picked
|
||||
for line in fileinput.input(["/lib/security/howdy/config.ini"], inplace = 1):
|
||||
print(line.replace("device_path = none", "device_path = " + picked), end="")
|
||||
for line in fileinput.input(["/lib/security/howdy/config.ini"], inplace=1):
|
||||
print(
|
||||
line
|
||||
.replace("device_path = none", "device_path = " + picked)
|
||||
.replace("use_cnn = false", "use_cnn = " + str(cuda_used).lower()),
|
||||
end=""
|
||||
)
|
||||
print("Camera ID saved")
|
||||
|
||||
# Secure the howdy folder
|
||||
handleStatus(subprocess.call(["chmod 744 -R /lib/security/howdy/"], shell=True))
|
||||
handleStatus(sc(["chmod 744 -R /lib/security/howdy/"], shell=True))
|
||||
|
||||
# Allow anyone to execute the python CLI
|
||||
handleStatus(subprocess.call(["chmod 755 /lib/security/howdy"], shell=True))
|
||||
handleStatus(subprocess.call(["chmod 755 /lib/security/howdy/cli.py"], shell=True))
|
||||
handleStatus(subprocess.call(["chmod 755 -R /lib/security/howdy/cli"], shell=True))
|
||||
os.chmod('/lib/security/howdy', 0o755)
|
||||
os.chmod('/lib/security/howdy/cli.py', 0o755)
|
||||
handleStatus(sc(["chmod 755 -R /lib/security/howdy/cli"], shell=True))
|
||||
print("Permissions set")
|
||||
|
||||
# Make the CLI executable as howdy
|
||||
handleStatus(subprocess.call(["ln -s /lib/security/howdy/cli.py /usr/local/bin/howdy"], shell=True))
|
||||
handleStatus(subprocess.call(["chmod +x /usr/local/bin/howdy"], shell=True))
|
||||
os.symlink("/lib/security/howdy/cli.py", "/usr/local/bin/howdy")
|
||||
os.chmod("/usr/local/bin/howdy", 0o755)
|
||||
print("Howdy command installed")
|
||||
|
||||
log("Adding howdy as PAM module")
|
||||
|
|
@ -149,10 +193,7 @@ inserted = False
|
|||
|
||||
# Open the PAM config file
|
||||
with open("/etc/pam.d/common-auth") as fp:
|
||||
# Read the first line
|
||||
line = fp.readline()
|
||||
|
||||
while line:
|
||||
for line in fp.readline():
|
||||
# Add the line to the output directly, we're not deleting anything
|
||||
outlines.append(line)
|
||||
|
||||
|
|
@ -179,9 +220,6 @@ with open("/etc/pam.d/common-auth") as fp:
|
|||
# Mark as inserted
|
||||
inserted = True
|
||||
|
||||
# Go to the next line
|
||||
line = fp.readline()
|
||||
|
||||
# Print a file Header
|
||||
print("\033[33m" + ">>> START OF /etc/pam.d/common-auth" + "\033[0m")
|
||||
|
||||
|
|
@ -196,19 +234,18 @@ print("\033[33m" + ">>> END OF /etc/pam.d/common-auth" + "\033[0m" + "\n")
|
|||
if "HOWDY_NO_PROMPT" not in os.environ:
|
||||
# Ask the user if this change is okay
|
||||
print("Lines will be insterted in /etc/pam.d/common-auth as shown above")
|
||||
ans = input("Apply this change? [y/N]: ")
|
||||
ans = input("Apply this change? [y/N]: ").strip().lower()
|
||||
|
||||
# Abort the whole thing if it's not
|
||||
if ans.lower().strip() != "y" or ans.lower().strip() == "yes":
|
||||
if ans not in ("y", "yes"):
|
||||
print("Interpreting as a \"NO\", aborting")
|
||||
sys.exit(1)
|
||||
|
||||
print("Adding lines to PAM\n")
|
||||
|
||||
# Write to PAM
|
||||
common_auth = open("/etc/pam.d/common-auth", "w")
|
||||
common_auth.write("".join(outlines))
|
||||
common_auth.close()
|
||||
with open("/etc/pam.d/common-auth", "w") as common_auth:
|
||||
common_auth.write("".join(outlines))
|
||||
|
||||
# Sign off
|
||||
print("Installation complete.")
|
||||
|
|
|
|||
Loading…
Reference in a new issue