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:
dmig 2018-12-09 13:30:25 +07:00
parent 9c2507ed13
commit ff02a723d4
No known key found for this signature in database
GPG key ID: A4A245B3AD37C4FC

131
debian/postinst vendored
View file

@ -10,14 +10,13 @@ def col(id):
return "\033[0m" return "\033[0m"
# Import required modules # Import required modules
import fileinput
import subprocess import subprocess
import time
import sys import sys
import os import os
import re import re
import signal import tarfile
import fileinput from shutil import rmtree, which
import urllib.parse
# Don't run unless we need to configure the install # Don't run unless we need to configure the install
# Will also happen on upgrade but we will catch that later on # 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)) print(col(3) + "Error while running last command" + col(0))
sys.exit(1) sys.exit(1)
sc = subprocess.call
# We're not in fresh configuration mode so don't continue the setup # We're not in fresh configuration mode so don't continue the setup
if not os.path.exists("/tmp/howdy_picked_device"): if not os.path.exists("/tmp/howdy_picked_device"):
@ -78,64 +78,108 @@ picked = in_file.read()
in_file.close() in_file.close()
# Remove the temporary file # 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") log("Upgrading pip to the latest version")
# Update pip # 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 log('Downloading dlib')
handleStatus(subprocess.call(["git", "clone", "--depth", "1", "https://github.com/davisking/dlib.git", "/tmp/dlib_clone"]))
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") log("Building dlib")
# Start the build without GPU # Start the build
handleStatus(subprocess.call(["cd /tmp/dlib_clone/; python3 setup.py install --yes USE_AVX_INSTRUCTIONS --no DLIB_USE_CUDA"], shell=True)) 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") log("Cleaning up dlib")
# Remove the no longer needed git clone # Remove the no longer needed git clone
handleStatus(subprocess.call(["rm", "-rf", "/tmp/dlib_clone"])) del sp
print("Temporary dlib files removed") 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") log("Configuring howdy")
# Manually change the camera id to the one picked # Manually change the camera id to the one picked
for line in fileinput.input(["/lib/security/howdy/config.ini"], inplace = 1): for line in fileinput.input(["/lib/security/howdy/config.ini"], inplace=1):
print(line.replace("device_path = none", "device_path = " + picked), end="") print(
line
.replace("device_path = none", "device_path = " + picked)
.replace("use_cnn = false", "use_cnn = " + str(cuda_used).lower()),
end=""
)
print("Camera ID saved") print("Camera ID saved")
# Secure the howdy folder # 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 # Allow anyone to execute the python CLI
handleStatus(subprocess.call(["chmod 755 /lib/security/howdy"], shell=True)) os.chmod('/lib/security/howdy', 0o755)
handleStatus(subprocess.call(["chmod 755 /lib/security/howdy/cli.py"], shell=True)) os.chmod('/lib/security/howdy/cli.py', 0o755)
handleStatus(subprocess.call(["chmod 755 -R /lib/security/howdy/cli"], shell=True)) handleStatus(sc(["chmod 755 -R /lib/security/howdy/cli"], shell=True))
print("Permissions set") print("Permissions set")
# Make the CLI executable as howdy # Make the CLI executable as howdy
handleStatus(subprocess.call(["ln -s /lib/security/howdy/cli.py /usr/local/bin/howdy"], shell=True)) os.symlink("/lib/security/howdy/cli.py", "/usr/local/bin/howdy")
handleStatus(subprocess.call(["chmod +x /usr/local/bin/howdy"], shell=True)) os.chmod("/usr/local/bin/howdy", 0o755)
print("Howdy command installed") print("Howdy command installed")
log("Adding howdy as PAM module") log("Adding howdy as PAM module")
@ -149,10 +193,7 @@ inserted = False
# Open the PAM config file # Open the PAM config file
with open("/etc/pam.d/common-auth") as fp: with open("/etc/pam.d/common-auth") as fp:
# Read the first line for line in fp.readline():
line = fp.readline()
while line:
# Add the line to the output directly, we're not deleting anything # Add the line to the output directly, we're not deleting anything
outlines.append(line) outlines.append(line)
@ -179,9 +220,6 @@ with open("/etc/pam.d/common-auth") as fp:
# Mark as inserted # Mark as inserted
inserted = True inserted = True
# Go to the next line
line = fp.readline()
# Print a file Header # Print a file Header
print("\033[33m" + ">>> START OF /etc/pam.d/common-auth" + "\033[0m") 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: if "HOWDY_NO_PROMPT" not in os.environ:
# Ask the user if this change is okay # Ask the user if this change is okay
print("Lines will be insterted in /etc/pam.d/common-auth as shown above") 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 # 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") print("Interpreting as a \"NO\", aborting")
sys.exit(1) sys.exit(1)
print("Adding lines to PAM\n") print("Adding lines to PAM\n")
# Write to PAM # Write to PAM
common_auth = open("/etc/pam.d/common-auth", "w") with open("/etc/pam.d/common-auth", "w") as common_auth:
common_auth.write("".join(outlines)) common_auth.write("".join(outlines))
common_auth.close()
# Sign off # Sign off
print("Installation complete.") print("Installation complete.")